#define MODULE_SIZE         1 * BLK_SIZE
#define BOOT_HIGH_LOC_MHD   ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + MODULE_SIZE)) >> 4)

DefinePrint("DD_BOOT_HIGH_LOC_MHD", "%08X", BOOT_HIGH_LOC_MHD << 4);

asm {
USE16
BMHD_START::
BMHD_CODE::
                CLD

                MOV         AX, BOOT_HIGH_LOC_MHD

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

                PUSHF
                PUSH        DS
                PUSH        ES
                PUSH        FS
                PUSH        GS
                PUSH        ECX
                PUSH        EBX
                PUSH        EDX
                PUSH        EBP

                MOV         ES, AX

                CALL        BMHD_GET_RIP
BMHD_GET_RIP:
                POP         BX
                SUB         BX, BMHD_GET_RIP-BMHD_START
                MOV         CX, BX
                SHR         BX, 4
//This copies this bootloader's code to 0x00096C00
                MOV         AX, CS
                PUSH        AX
                ADD         AX, BX
                MOV         DS, AX
                MOV         U16 [BMHD_OLD_CS_RIP     - BMHD_START], CX
                POP         U16 [BMHD_OLD_CS_RIP + 2 - BMHD_START]

                MOV         CX, MODULE_SIZE
                XOR         SI, SI
                XOR         DI, DI
                REP_MOVSB

                MOV         AX, BOOT_HIGH_LOC_MHD
                MOV         DS, AX

//The assembler doesn't support 16-bit very well.
                DU8         0xEA;   //JMP BOOT_HIGH_LOC_MHD:BMHD_HISTART
                DU16        BMHD_HISTART - BMHD_START, BOOT_HIGH_LOC_MHD;

BMHD_BIOS_DRIVE_NUM:    DU8         0;
BMHD_OLD_CS_RIP:        DU16        0, 0;
//Gets patched by BootHDIns().
BMHD_BLK_COUNT::        DU16        0;

BMHD_DAP:               DU8         16, 0, 1, 0; //One block at a time
BMHD_DAP_BUF:           DU16        0, 0;
//Gets patched by BootHDIns().
BMHD_DAP_BLK::  //64-bit
BMHD_DAP_BLK_LO:        DU32        0;
BMHD_DAP_BLK_HI:        DU32        0;

BMHD_HISTART:
                MOV         U8 [BMHD_BIOS_DRIVE_NUM - BMHD_START], DL //Passed in by BIOS
                MOV         AX,  BOOT_RAM_BASE / 16
                MOV         ES,  AX
                XOR         ECX, ECX
                MOV         CX,  U16 [BMHD_BLK_COUNT - BMHD_START]

@@05:           PUSH        CX          //Block count

//READ BLOCK
                PUSH        ES          //Buf seg
                MOV         AX, ES
                MOV         U16 [BMHD_DAP_BUF + 2 - BMHD_START], AX //ES:0000
                MOV         SI, BMHD_DAP - BMHD_START //DS:SI=DAP
                MOV         AH, 0x42
                MOV         DL, U8 [BMHD_BIOS_DRIVE_NUM - BMHD_START]
                INT         0x13

                POP         AX          //ES
                ADD         AX, BLK_SIZE / 16
                MOV         ES, AX
                INC         U32 [BMHD_DAP_BLK_LO - BMHD_START]
                JNZ         @@10
                INC         U32 [BMHD_DAP_BLK_HI - BMHD_START]

@@10:           POP         CX
                LOOP        @@05

                MOV         DL,  U8  [BMHD_BIOS_DRIVE_NUM - BMHD_START]
                MOV         EBX, U32 [BMHD_OLD_CS_RIP     - BMHD_START]
//The assembler doesn't support 16-bit very well.
                DU8         0xEA;   //JMP BOOT_RAM_BASE:0000
                DU16        0, BOOT_RAM_BASE / 16;
//Continues here BMHD2_START
BMHD_END::
#assert BMHD_END-BMHD_START <= 440
}