#define BOOT_HIGH_LOC_DVD       ((BOOT_RAM_LIMIT-\
                                (BOOT_STK_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_STK_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

//My 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_DRV_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_MSG:
        DU8     "Loading TempleOS",0;

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

//These get patched.
BDVD_BLK_LO::           DU16    0;
BDVD_BLK_HI::           DU16    0;
BDVD_BLK_CNT::          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_DRV_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_MSG-BDVD_START
        CALL    BDVD_PUTS
@@10:   JMP     @@10

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

        MOV     AX,BOOT_RAM_BASE/16
        MOV     ES,AX
        XOR     ECX,ECX
        MOV     CX,U16 [BDVD_BLK_CNT-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 cnt

//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_DRV_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_CNT-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 BootDVDProbe().
        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

//My 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.HC
BDVD_END::
#assert BDVD_END-BDVD_START<DVD_BOOT_LOADER_SIZE
}