176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* NOTE: this boot sector contains instructions that need at least an 80186.
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Yes, as86 has a bug somewhere in the valid instruction set checks.
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*	floppyload.S Copyright (C) 1991, 1992 Linus Torvalds
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	modified by Drew Eckhardt
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	modified by Bruce Evans (bde)
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * floppyprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * It then loads the system at SYSSEG<<4, using BIOS interrupts.
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The loader has been made as simple as possible, and continuous read errors
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * will result in a unbreakable loop. Reboot by hand. It loads pretty fast by
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * getting whole tracks at a time whenever possible.
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_ONLY )
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.equ	BOOTSEG, 0x07C0			/* original address of boot-sector */
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.equ	SYSSEG, 0x1000			/* system loaded at SYSSEG<<4 */
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.org	0
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.arch i386
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.text
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.section ".prefix", "ax", @progbits
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.code16
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmango:
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x2000-12, %di		/* 0x2000 is arbitrary value >= length */
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					/* of bootsect + room for stack + 12 for */
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					/* saved disk parm block */
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$BOOTSEG, %ax
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%ds
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%es
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%ss			/* put stack at BOOTSEG:0x4000-12. */
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%di,%sp
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Many BIOS's default disk parameter tables will not recognize multi-sector
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * reads beyond the maximum sector number specified in the default diskette
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * parameter tables - this may mean 7 sectors in some cases.
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Since single sector reads are slow and out of the question, we must take care
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * of this by creating new parameter tables (for the first disk) in RAM.  We
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * will set the maximum sector count to 36 - the most we will encounter on an
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ED 2.88.  High doesn't hurt.	Low does.
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Segments are as follows: ds=es=ss=cs - BOOTSEG
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%cx,%cx
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%cx,%es			/* access segment 0 */
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x78, %bx		/* 0:bx is parameter table address */
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ds			/* save ds */
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 0:bx is parameter table address */
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ldsw	%es:(%bx),%si		/* loads ds and si */
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%es			/* ax is BOOTSECT (loaded above) */
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$6, %cl			/* copy 12 bytes */
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cld
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%di			/* keep a copy for later */
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rep
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movsw				/* ds:si is source, es:di is dest */
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%di
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$36,%es:4(%di)
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%cx,%ds			/* access segment 0 */
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xchgw	%di,(%bx)
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%es,%si
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xchgw	%si,2(%bx)
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%ds			/* restore ds */
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%di, dpoff		/* save old parameters */
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%si, dpseg		/* to restore just before finishing */
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ds
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%es			/* reload es */
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Note that es is already set up.  Also cx is 0 from rep movsw above. */
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%ah,%ah			/* reset FDC */
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%dl,%dl
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Get disk drive parameters, specifically number of sectors/track.
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * It seems that there is no BIOS call to get the number of sectors.  Guess
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 15 if sector 15 can be read.	Otherwise guess 9.
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$disksizes, %si		/* table of sizes to try */
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprobe_loop:
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lodsb
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cbtw				/* extend to word */
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, sectors
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	$disksizes+4, %si
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jae	got_sectors		/* if all else fails, try 9 */
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xchgw	%cx,%ax			/* cx = track and sector */
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%dx,%dx			/* drive 0, head 0 */
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0200, %bx		/* address after boot sector */
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					/*   (512 bytes from origin, es = cs) */
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0201, %ax		/* service 2, 1 sector */
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	probe_loop		/* try next value */
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmangot_sectors:
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$msg1end-msg1, %cx
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$msg1, %si
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_str
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ok, we've written the Loading... message, now we want to load the system */
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$SYSSEG, %ax
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%es			/* segment of SYSSEG<<4 */
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%es
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_it
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This turns off the floppy drive motor, so that we enter the kernel in a
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * known state, and don't have to worry about it later.
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x3f2, %dx
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%al,%al
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	outb	%al,%dx
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_nl
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pop	%es			/* = SYSSEG */
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Restore original disk parameters */
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x78, %bx
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	dpoff, %di
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	dpseg, %si
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%ax,%ax
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%ds
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%di,(%bx)
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%si,2(%bx)
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Everything now loaded.  %es = SYSSEG, so %es:0000 points to
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 * start of loaded image.
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 */
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Jump to loaded copy */
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ljmp	$SYSSEG, $start_runtime
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanendseg:	.word SYSSEG
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.section ".zinfo.fixup", "a", @progbits	/* Compressor fixups */
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii	"ADDW"
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.long	endseg
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.long	16
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.long	0
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.previous
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * boundaries are crossed. We try to load it as fast as possible, loading whole
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * tracks whenever we can.
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * in:	es - starting address segment (normally SYSSEG)
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_it:
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0,sread		/* load whole image including prefix */
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%es,%ax
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	testw	$0x0fff, %ax
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandie:	jne	die			/* es must be at 64kB boundary */
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%bx,%bx			/* bx is starting address within segment */
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanrp_read:
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%es,%ax
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%bx,%dx
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$4, %cl
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shrw	%cl,%dx			/* bx is always divisible by 16 */
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	%dx,%ax
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	endseg, %ax	/* have we loaded all yet? */
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jb	ok1_read
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanok1_read:
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	sectors, %ax
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	subw	sread, %ax
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%cx
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shlw	$9, %cx
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	%bx,%cx
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnc	ok2_read
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	je	ok2_read
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%ax,%ax
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	subw	%bx,%ax
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shrw	$9, %ax
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanok2_read:
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	read_track
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%cx
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	sread, %ax
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpw	sectors, %ax
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	ok3_read
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$1, %ax
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	subw	head, %ax
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jne	ok4_read
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	track
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanok4_read:
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, head
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%ax,%ax
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanok3_read:
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax, sread
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	shlw	$9, %cx
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	%cx,%bx
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jnc	rp_read
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%es,%ax
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addb	$0x10, %ah
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%ax,%es
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorw	%bx,%bx
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	rp_read
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanread_track:
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pusha
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bx
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bp			/* just in case the BIOS is buggy */
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0e2e, %ax		/* 0x2e = . */
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0007, %bx
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%bp
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%bx
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%ax
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	track, %dx
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	sread, %cx
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	incw	%cx
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%dl,%ch
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	head, %dx
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	%dl,%dh
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andw	$0x0100, %dx
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$2, %ah
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%dx			/* save for error dump */
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cx
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%bx
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jc	bad_rt
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	$8, %sp
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popa
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbad_rt: pushw	%ax			/* save error code */
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_all		/* ah = error, al = read */
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%ah,%ah
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	xorb	%dl,%dl
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x13
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	$10, %sp
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popa
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jmp	read_track
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* print_all is for debugging purposes.	It will print out all of the registers.
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The assumption is that this is called from a routine, with a stack frame like
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	dx
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	cx
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	bx
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	ax
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	error
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *	ret <- sp
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_all:
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_nl		/* nl for readability */
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$5, %cx			/* error code + 4 registers */
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%sp,%bp
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_loop:
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cx			/* save count left */
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cmpb	$5, %cl
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	jae	no_reg			/* see if register name is needed */
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0xe05+0x41-1, %ax
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	subb	%cl,%al
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x58, %al		/* 'X' */
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x3A, %al		/* ':' */
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanno_reg:
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addw	$2, %bp			/* next register */
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_hex		/* print it */
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x20, %al		/* print a space */
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popw	%cx
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	loop	print_loop
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_nl		/* nl for readability */
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_str:
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x0e, %ah		/* write char, tty mode */
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprloop:
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lodsb
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	loop	prloop
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_nl:
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0xe0d, %ax		/* CR */
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0xa, %al		/* LF */
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_hex:
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	(%bp),%dx		/* load word into dx */
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$4, %cl
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x0e, %ah		/* write char, tty mode */
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_digit
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_digit
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	print_digit
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* fall through */
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanprint_digit:
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rol	%cl,%dx			/* rotate so that lowest 4 bits are used */
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movb	$0x0f, %al		/* mask for nybble */
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	andb	%dl,%al
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	addb	$0x90, %al		/* convert al to ascii hex (four instructions) */
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	daa
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	adcb	$0x40, %al
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	daa
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int	$0x10
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	ret
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansread:	.word 0				/* sectors read of current track */
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanhead:	.word 0				/* current head */
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantrack:	.word 0				/* current track */
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmansectors:
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.word 0
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandpseg:	.word 0
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandpoff:	.word 0
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmandisksizes:
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.byte 36,18,15,9
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmsg1:
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.ascii "Loading ROM image"
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmsg1end:
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.org 510, 0
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.word 0xAA55
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstart_runtime:
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Install gPXE */
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	install
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Set up real-mode stack */
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	%bx, %ss
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	movw	$_estack16, %sp
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Jump to .text16 segment */
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%ax
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	$1f
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	lret
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	.section ".text16", "awx", @progbits
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman1:
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushl	$main
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	pushw	%cs
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	prot_call
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	popl	%ecx /* discard */
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Uninstall gPXE */
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	call	uninstall
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Boot next device */
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	int $0x18
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
382