#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 blk at a time
BDVD_DAP_BUF:                           DU16            0, 0;
BDVD_DAP_BLK:                           DU64            0;
 
BDVD_TEMPLEOS_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_TEMPLEOS_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                      //Blk count

//READ BLK
                                PUSH            AX                      //Blk lo
                                PUSH            DX                      //Blk 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 IDEBootDVDProbe().
                                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.CC
BDVD_END::
#assert BDVD_END-BDVD_START < DVD_BOOT_LOADER_SIZE
}