#warning "Needs fixing up for gpxe"

#if 0

/****************************************************************\

hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen

This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
http://www.programmersheaven.com/zone5/cat469/40546.htm.

This software may be used and distributed according to the terms
of the GNU Public License (GPL), incorporated herein by reference.

hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.

Actions performed by hdprefix:
1) Load the MBR to LOADSEG:0
2) Check which partition is active (or try first partition if none active)
3) Check wether LBA is supported.
3a) LBA
3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
3b) CHS (standard)
3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
4) Check loaded bootsector for BOOTMAGIC code.
5) Jump to payload LOADSEG:ENTRYPOINT.

Output with failure points (!#):
---
Loading (!1)partition #
Std. BIOS(!2) | Ext. BIOS(!3)
Booting...(!4)
(!5)
---

!1: Failed to load MBR with Int13,ah=2.
!2: Failed to load bootrecord+payload with Int13,ah=2.
!3: Failed to load bootrecord+payload with Int13,ah=42.
!4: Invalid BOOTMAGIC in loaded bootrecord.
!5: Jumping to payload.

\*****************************************************************/
 
.equ	BOOTSEG,	0x07c0
.equ	LOADSEG,	0x1000
.equ	ENTRYPOINT,	_start

.equ	BOOTMAGIC,	0x0aa55

.equ	partition_table,	0x1be
.equ	partition_rec_size,	0x10

.equ	boot_ind,	0	/* 80h=active */
.equ	start_head,	1
.equ	start_sector,	2	/* bits 0-5 */
.equ	start_cyl,	3	/* bits 8,9 in bits 6,7 of sector */
.equ	os_ind,		4	/* os indicator */
.equ	end_head,	5
.equ	end_sector,	6	/* bits 0-5 */
.equ	end_track,	7	/* bits 8,9 in bits 6,7 of sector */
.equ	nsect,		8	/* sectors preceding partition */
.equ	lenght,		0x0c	/* length of partition in sectors */

/-------------------------------------------------------------

	.arch i386
	.text
	.section ".prefix", "ax", @progbits
	.code16
	 
bootstart:
	jmp	$BOOTSEG,$_go		/* reload cs:ip */


/****************************************************************/
/* support routines.						*/
/*--------------------------------------------------------------*/
_failed:
	movw	$BOOTSEG,%ax
	movw	%ax,%ds
	movw	$_failed_msg_end-_failed_msg,%cx
	movw	$_failed_msg,%si
	call	_print_str

	/* stop execution - should probably have option to auto-reboot after delay. */
_failed_loop:
	jmp	_failed_loop

/*--------------------------------------------------------------*/
_print_str:
	/* cx = count, ds:si = string. */
	movw	$0x0007,%bx
	movb	$0x0e,%ah
_print_loop:
	lodsb
	int	$0x10
	loop	_print_loop
	ret

/*--------------------------------------------------------------*/			
_print_char:
	/* al = char. */
	movw	$0x0007,%bx
	movb	$0x0e,%ah
	int	$0x10
	ret

/*--------------------------------------------------------------*/
_print_nl:
	/* - */
	movb	$0x0d,%al
	call	_print_char
	movb	$0x0a,%al
	call	_print_char
	ret

/*--------------------------------------------------------------*/
_print_hex:
	/* dx = value */
	movb	$0x0e,%ah	/* write char, tty mode */
	movw	$0x0007,%bx	/* page 0, attribute 7 (normal) */
	call	_print_digit
	call	_print_digit
	call	_print_digit
	/* fall through */
_print_digit:
	rolw	$4,%dx		/* rotate so that lowest 4 bits are used */
	movb	$0x0f,%al	/* mask for nibble */
	andb	%dl,%al
	addb	$0x90,%al	/* convert al to ascii hex (four instructions) */
	daa
	adcb	$0x40,%al
	daa
	int	$0x10
	ret

/****************************************************************/


_go:
	cli
	movw	$BOOTSEG,%ax
	movw	%ax,%ds
	movw	%ax,%ss
	movw	$0x2000,%sp	/* good large stack. */
	sti
	cld
	movw	$LOADSEG,%ax
	movw	%ax,%es

	movw	$_load_msg_end-_load_msg,%cx
	movw	$_load_msg,%si
	call	_print_str

/*--- load MBR so we can use its partition table. ---*/
	xorw	%bx,%bx
	movw	$0x0001,%cx	/* chs: 0,0,1 */
	movb	%bh,%dh		/* - */
	movb	$0x80,%dl
	movw	$0x0201,%ax	/* read one sector (MBR) */
	int	$0x13
	jc	_failed

/*--- find the active partition ---*/
	movw	$_part_msg_end-_part_msg,%cx
	movw	$_part_msg,%si
	call	_print_str

	movw	$partition_table,%di
	movw	$4,%cx
_partition_loop:
	cmpb	$0x80,%es:(%di)		/* active? */
	je	_partition_found
	addw	$partition_rec_size,%di
	loop	_partition_loop

	/*- no partitions marked active - use 1. partition. */
	movw	$partition_table,%di
	movw	$4,%cx

_partition_found:
	movb	$'5',%al			/* convert to ascii */
	subb	%cl,%al
	call	_print_char
	call	_print_nl

/*--- check for lba support ---*/
	movw	$0x55aa,%bx
	movb	$0x80,%dl
	movb	$0x41,%ah
	int	$0x13
	jc	__bios
	cmpw	$0x0aa55,%bx
	jnz	__bios
	testb	$1,%cl
	jz	__bios

/*--- use lba bios calls to read sectors ---*/
_lba:
	movw	$_extbios_msg_end-_extbios_msg,%cx
	movw	$_extbios_msg,%si
	call	_print_str

	movw	%es:nsect(%di),%ax
	movw	%ax,_bios_lba_low
	movw	%es:nsect+2(%di),%ax
	movw	%ax,_bios_lba_high
	movb	$0x80,%dl
	movw	$_disk_address_packet,%si
	movw	$0x4200,%ax	/* read */
	int	$0x13
	jc	_failed
	jmp	__loaded

/*--- use standard bios calls to read sectors ---*/
__bios:
	movw	$_stdbios_msg_end-_stdbios_msg,%cx
	movw	$_stdbios_msg,%si
	call	_print_str

	movw	_disk_address_packet+2(,1),%ax	/* only low byte is used. */
	xorw	%bx,%bx
	movw	%es:start_sector(%di),%cx
	movb	%es:start_head(%di),%dh
	movb	$0x80,%dl
	movb	$0x02,%ah
	int	$0x13
	jc	_failed

__loaded:
	movw	$_boot_msg_end-_boot_msg,%cx
	movw	$_boot_msg,%si
	call	_print_str

	/* check if it has a valid bootrecord. */
	cmpw	$BOOTMAGIC,%es:510(,1)
	jne	_failed
	call	_print_nl

	/* call the payload. */
	pushl	$0		/* No parameters to preserve for exit path */
	pushw	$0		/* Use prefix exit path mechanism */
	jmp	$LOADSEG,$ENTRYPOINT

	.section ".text16", "ax", @progbits
	.globl	prefix_exit
prefix_exit:
	int	$0x19		/* should try to boot machine */
	.globl	prefix_exit_end
prefix_exit_end:
	.previous
	 

/*--------------------------------------------------------------*/

_load_msg:	.ascii	"Loading "
_load_msg_end:
_part_msg:	.ascii	"partition "
_part_msg_end:
_boot_msg:	.ascii	"Booting..."
_boot_msg_end:
_stdbios_msg:	.ascii	"Std. BIOS\r\n"
_stdbios_msg_end:
_extbios_msg:	.ascii	"Ext. BIOS\r\n"
_extbios_msg_end:
_failed_msg:	.ascii	"FAILED!!!\r\n"
_failed_msg_end:


/*--------------------------------------------------------------*/

_disk_address_packet:
		.byte	0x10		/* size of the packet */
		.byte	0		/* reserved */
		.word	_verbatim_size_sct	/* number of sectors to read */
		.word	0x0000		/* offset */
		.word	LOADSEG 	/* segment of buffer */
_bios_lba_low:	.word	0
_bios_lba_high:	.word	0
		.word	0
		.word	0

	.rept 32
		.byte	0
	.endr


/*--- Partition table ------------------------------------------*/

	.org 446, 0
	.rept 64
		.byte	0
	.endr


/*--- Magic code -----------------------------------------------*/
	.org 510, 0
		.word BOOTMAGIC

/*** END ********************************************************/
#endif
