#define BOOT_HIGH_LOC_DVD           ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + DVD_BOOT_LOADER_SIZE)) >> 4)

DefinePrint("DD_BOOT_HIGH_LOC_DVD",     "%08X", BOOT_HIGH_LOC_DVD << 4);
DefinePrint("DD_BOOT_HIGH_LOC_DVD_END", "%08X", BOOT_RAM_LIMIT - 1);

asm {
USE16
BDVD_START::
//DL is supposed to have the BIOS drive number
                CLD
                MOV         AX, BOOT_HIGH_LOC_DVD
                MOV         ES, AX

                CLI
                MOV         SS, AX
                MOV         SP, BOOT_STACK_SIZE + DVD_BOOT_LOADER_SIZE
                STI

                CALL        BDVD_GET_RIP
BDVD_GET_RIP:
                POP         BX
                SUB         BX, BDVD_GET_RIP - BDVD_START
                SHR         BX, 4
//This copies this bootloader's code to 0x00096600
                MOV         AX, CS
                ADD         AX, BX
                MOV         DS, AX
                MOV         CX, DVD_BOOT_LOADER_SIZE
                XOR         SI, SI
                XOR         DI, DI
                REP_MOVSB

                MOV         AX, BOOT_HIGH_LOC_DVD
                MOV         DS, AX

//The assembler doesn't support 16-bit very well.
                DU8         0xEA;   //JMP BOOT_HIGH_LOC_DVD:BDVD_MAIN
                DU16        BDVD_MAIN - BDVD_START, BOOT_HIGH_LOC_DVD;

BDVD_BIOS_DRIVE_NUM:        DU8         0;
BDVD_PAGE:                  DU8         0;

BDVD_DAP:                   DU8         16, 0, 1, 0; //One block at a time
BDVD_DAP_BUF:               DU16        0, 0;
BDVD_DAP_BLK:               DU64        0;
 
BDVD_ZEALOS_MESSAGE:        DU8         "Loading ZealOS", 0;

BDVD_NOT64_MESSAGE:         DU8         "ZealOS requires a 64-bit capable processor.\n\r", 0;

//These get patched.
BDVD_BLK_LO::               DU16        0;
BDVD_BLK_HI::               DU16        0;
BDVD_BLK_COUNT::            DU16        0;
BDVD_SHIFT_BLKS::           DU16        0;
BDVD_PROGRESS_STEP::        DU32        0;
BDVD_PROGRESS_VAL::         DU32        0;

BDVD_PUT_CHAR::
                MOV         AH, 0xE
                MOV         BL, 7 //Might be foreground color on some BIOS's
                MOV         BH, U8 [BDVD_PAGE - BDVD_START]
                INT         0x10
BDVD_RET::
                RET
BDVD_PUTS::
@@1:            LODSB
                TEST        AL, AL
                JZ          BDVD_RET
                CALL        BDVD_PUT_CHAR
                JMP         @@1

BDVD_MAIN::
                MOV         U8 [BDVD_BIOS_DRIVE_NUM - BDVD_START], DL //Passed in by BIOS

                MOV         AH, 0xF
                INT         0x10
                MOV         U8 [BDVD_PAGE - BDVD_START], BH //Video page

                MOV         EAX, 0x80000000
                CPUID
                CMP         EAX, 0x80000001
                JB          @@05

                MOV         EAX, 0x80000001
                CPUID
                BT          EDX, 29
                JC          @@15
@@05:           MOV         SI, BDVD_NOT64_MESSAGE - BDVD_START
                CALL        BDVD_PUTS
@@10:           JMP         @@10

@@15:           MOV         SI, BDVD_ZEALOS_MESSAGE - BDVD_START
                CALL        BDVD_PUTS

                MOV         AX,  BOOT_RAM_BASE / 16
                MOV         ES,  AX
                XOR         ECX, ECX
                MOV         CX,  U16 [BDVD_BLK_COUNT - BDVD_START]

                MOV         EAX, (80 - 7 - 9) * 65536   //80 columns
                XOR         EDX, EDX
                DIV         ECX
                MOV         U32 [BDVD_PROGRESS_STEP - BDVD_START], EAX
                MOV         U32 [BDVD_PROGRESS_VAL  - BDVD_START], 0

                MOV         AX, U16 [BDVD_BLK_LO - BDVD_START]
                MOV         DX, U16 [BDVD_BLK_HI - BDVD_START]

@@20:           PUSH        CX          //Block count

//READ BLOCK
                PUSH        AX          //Block lo
                PUSH        DX          //Block hi
                PUSH        ES          //Buf seg
                MOV         U16 [BDVD_DAP_BLK     - BDVD_START], AX
                MOV         U16 [BDVD_DAP_BLK + 2 - BDVD_START], DX
                MOV         AX, ES
                MOV         U16 [BDVD_DAP_BUF + 2 - BDVD_START], AX //ES:0000
                MOV         SI, BDVD_DAP - BDVD_START //DS:SI=DAP
                MOV         AH, 0x42
                MOV         DL, U8 [BDVD_BIOS_DRIVE_NUM - BDVD_START]
                INT         0x13

                POP         AX          //ES
                ADD         AX, DVD_BLK_SIZE / 16
                MOV         ES, AX
                POP         DX
                POP         AX
                INC         AX
                JNZ         @@25
                INC         DX

@@25:           PUSH        AX
                MOV         BX,  U16 [BDVD_PROGRESS_VAL + 2 - BDVD_START]
                MOV         EAX, U32 [BDVD_PROGRESS_STEP    - BDVD_START]
                ADD         U32 [BDVD_PROGRESS_VAL     - BDVD_START], EAX
                CMP         U16 [BDVD_PROGRESS_VAL + 2 - BDVD_START], BX
                JE          @@30
                MOV         AL,  '.'
                CALL        BDVD_PUT_CHAR
@@30:           POP         AX

                POP         CX
                LOOP        @@20

//Shift backward to align
                PUSH        DS
                MOV         BX, U16 [BDVD_SHIFT_BLKS - BDVD_START]
                SHL         BX, BLK_SIZE_BITS - 4
                MOV         CX, U16 [BDVD_BLK_COUNT - BDVD_START]
                MOV         AX, BOOT_RAM_BASE / 16
                MOV         ES, AX
                ADD         AX, BX
                MOV         DS, AX
@@35:           PUSH        CX
                XOR         SI, SI
                XOR         DI, DI
                MOV         CX, DVD_BLK_SIZE / 4
                REP_MOVSD
                MOV         AX, DS
                ADD         AX, DVD_BLK_SIZE / 16
                MOV         DS, AX
                MOV         AX, ES
                ADD         AX, DVD_BLK_SIZE / 16
                MOV         ES, AX
                POP         CX
                LOOP        @@35
                POP         DS

//See AHCIBootDVDProbeAll().
                MOV         EBX, U32 [BDVD_BLK_LO     - BDVD_START]
                MOV         AX,  U16 [BDVD_SHIFT_BLKS - BDVD_START]
                SHL         EAX, 16
                MOV         AX,  BOOT_SRC_DVD  //See sys_boot_src

//The assembler doesn't support 16-bit very well.
                DU8         0xEA;   //JMP BOOT_RAM_BASE:0000
                DU16        0, BOOT_RAM_BASE / 16;
//Continues here ::/Kernel/KStart16.ZC
BDVD_END::
#assert BDVD_END-BDVD_START < DVD_BOOT_LOADER_SIZE
}