#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 0x$TX,"00096600",D="DD_BOOT_HIGH_LOC_DVD"$
				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_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 ZenithOS", 0;

BDVD_NOT64_MESSAGE:			DU8 		"ZenithOS 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 $LK,"BootDVDProbe",A="MN: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  //$MA-X+PU,"See sys_boot_src",LM="Find(\"sys_boot_src\",\"/*\");View;\n"$

//My assembler doesn't support 16-bit very well.
				DU8 		0xEA; 	//JMP BOOT_RAM_BASE:0000
				DU16		0, BOOT_RAM_BASE / 16;
//Continues here $LK,"::/Kernel/KStart16.CC",A="FL:::/Kernel/KStart16.CC,1"$
BDVD_END::
#assert BDVD_END-BDVD_START < DVD_BOOT_LOADER_SIZE
}
