wok-current diff etherboot/stuff/etherboot-prefix.u @ rev 11689

ntop: update bdep
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Feb 18 17:18:01 2012 +0100 (2012-02-18)
parents e0c2f4f235e9
children
line diff
     1.1 --- a/etherboot/stuff/etherboot-prefix.u	Thu Apr 10 22:34:56 2008 +0000
     1.2 +++ b/etherboot/stuff/etherboot-prefix.u	Sat Feb 18 17:18:01 2012 +0100
     1.3 @@ -1,6 +1,6 @@
     1.4  --- etherboot-5.4.3/src/arch/i386/prefix/liloprefix.S
     1.5  +++ etherboot-5.4.3/src/arch/i386/prefix/liloprefix.S
     1.6 -@@ -1,92 +1,393 @@
     1.7 +@@ -1,92 +1,377 @@
     1.8  -/*
     1.9  -	Copyright (C) 2000, Entity Cyber, Inc.
    1.10  -
    1.11 @@ -39,10 +39,7 @@
    1.12  -	of setup code are contained in the image.
    1.13  -
    1.14  -*/
    1.15 -+/* NOTE: this boot sector contains instructions that need at least an 80186.
    1.16 -+ * Yes, as86 has a bug somewhere in the valid instruction set checks.
    1.17 -+ *
    1.18 -+ * SYS_SIZE is the number of clicks (16 bytes) to be loaded.  For Etherboot
    1.19 ++/* SYS_SIZE is the number of clicks (16 bytes) to be loaded.  For Etherboot
    1.20  + * purposes, we need to load everything but the boot sector itself, i.e. 32
    1.21  + * clicks less than the size of the entire (verbatim) image.  The image size
    1.22  + * is practically limited only by the available base memory size.
    1.23 @@ -91,14 +88,13 @@
    1.24  +	.text
    1.25  +	.section ".prefix", "ax", @progbits
    1.26  +	.code16
    1.27 - 
    1.28 --bootsector: 
    1.29 --	jmp	$BOOTSEG, $go - _prefix	/* reload cs:ip to match relocation addr */
    1.30 ++
    1.31  +	call	here
    1.32  +here:
    1.33  +	pop	%ax
    1.34  +	cmpw	$0x103, %ax		/* COM entry point is cs:0x100 */
    1.35  +	jne	bootsector
    1.36 ++
    1.37  +/* We need a real mode stack that won't be stomped on by Etherboot
    1.38  +   which starts at 0x20000. Choose something that's sufficiently high,
    1.39  +   but not in DOC territory. Note that we couldn't do this in a real
    1.40 @@ -113,18 +109,14 @@
    1.41  +	movw	%ax, %ss
    1.42  +	movw	$STACK_SIZE, %sp
    1.43  +
    1.44 -+	pushl	$0	/* No parameters to preserve for exit path */
    1.45 -+	pushw	$0	/* Dummy return address - use prefix_exit */
    1.46 -+
    1.47  +	/* Calculate segment address of image start */
    1.48  +	pushw	%cs
    1.49  +	popw	%ax
    1.50  +	addw	$(0x100/16), %ax
    1.51 -+	pushw	%ax
    1.52 -+	pushw	$_start
    1.53 -+	/* Calculated lcall to _start with %cs:0000 = image start */
    1.54 -+	lret
    1.55 -+
    1.56 ++	jmp	go_setup_code
    1.57 + 
    1.58 +-bootsector: 
    1.59 +-	jmp	$BOOTSEG, $go - _prefix	/* reload cs:ip to match relocation addr */
    1.60  +bootsector:
    1.61  +	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */
    1.62   go: 
    1.63 @@ -197,15 +189,18 @@
    1.64  + * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
    1.65  + * 15 if sector 15 can be read.	Otherwise guess 9.
    1.66  + */
    1.67 -+
    1.68 + 
    1.69 +-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
    1.70 +-	movb	$0x0e, %ah		/* write char, tty mode */
    1.71 +-prloop: 
    1.72  +	movw	$disksizes, %si		/* table of sizes to try */
    1.73  +
    1.74  +probe_loop: 
    1.75 -+	lodsb
    1.76 + 	lodsb
    1.77 ++	orb	%al, %al
    1.78 ++	je	got_sectors		/* if all else fails, try 9 */
    1.79  +	cbtw				/* extend to word */
    1.80  +	movw	%ax, sectors
    1.81 -+	cmpw	$disksizes+4, %si
    1.82 -+	jae	got_sectors		/* if all else fails, try 9 */
    1.83  +	xchgw	%cx,%ax			/* cx = track and sector */
    1.84  +	xorw	%dx,%dx			/* drive 0, head 0 */
    1.85  +	movw	$0x0200, %bx		/* address after boot sector */
    1.86 @@ -250,9 +245,8 @@
    1.87  +
    1.88  +/* after that (everything loaded), we call to the .ROM file loaded. */
    1.89  +
    1.90 -+	pushl	$0		/* No parameters to preserve for exit path */
    1.91 -+	pushw	$0		/* Use prefix exit path mechanism */
    1.92 -+	ljmp	$SYSSEG, $_start
    1.93 ++	movw	$SYSSEG, %ax
    1.94 ++	jmp	go_setup_code
    1.95  +
    1.96  +/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
    1.97  + * boundaries are crossed. We try to load it as fast as possible, loading whole
    1.98 @@ -279,13 +273,13 @@
    1.99  +	movw	sectors, %ax
   1.100  +	subw	sread, %ax
   1.101  +	movw	%ax,%cx
   1.102 -+	shlw	$9, %cx
   1.103 ++	shlw	$9, %cx			/* 80186 opcode */
   1.104  +	addw	%bx,%cx
   1.105  +	jnc	ok2_read
   1.106  +	je	ok2_read
   1.107  +	xorw	%ax,%ax
   1.108  +	subw	%bx,%ax
   1.109 -+	shrw	$9, %ax
   1.110 ++	shrw	$9, %ax			/* 80186 opcode */
   1.111  +ok2_read: 
   1.112  +	call	read_track
   1.113  +	movw	%ax,%cx
   1.114 @@ -301,7 +295,7 @@
   1.115  +	xorw	%ax,%ax
   1.116  +ok3_read: 
   1.117  +	movw	%ax, sread
   1.118 -+	shlw	$9, %cx
   1.119 ++	shlw	$9, %cx			/* 80186 opcode */
   1.120  +	addw	%cx,%bx
   1.121  +	jnc	rp_read
   1.122  +	movw	%es,%ax
   1.123 @@ -311,24 +305,21 @@
   1.124  +	jmp	rp_read
   1.125  +
   1.126  +read_track: 
   1.127 -+	pusha
   1.128 ++	pusha				/* 80186 opcode */
   1.129  +	pushw	%ax
   1.130  +	pushw	%bx
   1.131  +	pushw	%bp			/* just in case the BIOS is buggy */
   1.132 -+	movw	$0x0e2e, %ax		/* 0x2e = . */
   1.133 -+	movw	$0x0007, %bx
   1.134 -+	int	$0x10
   1.135 ++	movb	$0x2e, %al		/* 0x2e = . */
   1.136 ++	call	print_char
   1.137  +	popw	%bp
   1.138  +	popw	%bx
   1.139  +	popw	%ax
   1.140  +
   1.141 -+	movw	track, %dx
   1.142  +	movw	sread, %cx
   1.143  +	incw	%cx
   1.144 -+	movb	%dl,%ch
   1.145 -+	movw	head, %dx
   1.146 -+	movb	%dl,%dh
   1.147 -+	andw	$0x0100, %dx
   1.148 ++	movb	track, %ch
   1.149 ++	movw	$0x0100, %dx
   1.150 ++	andb	head, %dh
   1.151  +	movb	$2, %ah
   1.152  +
   1.153  +	pushw	%dx			/* save for error dump */
   1.154 @@ -339,7 +330,7 @@
   1.155  +	int	$0x13
   1.156  +	jc	bad_rt
   1.157  +	addw	$8, %sp
   1.158 -+	popa
   1.159 ++	popa				/* 80186 opcode */
   1.160  +	ret
   1.161  +
   1.162  +bad_rt: pushw	%ax			/* save error code */
   1.163 @@ -350,7 +341,7 @@
   1.164  +	int	$0x13
   1.165  +
   1.166  +	addw	$10, %sp
   1.167 -+	popa
   1.168 ++	popa				/* 80186 opcode */
   1.169  +	jmp	read_track
   1.170  +
   1.171  +/* print_all is for debugging purposes.	It will print out all of the registers.
   1.172 @@ -365,6 +356,7 @@
   1.173  +
   1.174  +print_all: 
   1.175  +	call	print_nl		/* nl for readability */
   1.176 ++					/* print_nl update ah and bx */
   1.177  +	movw	$5, %cx			/* error code + 4 registers */
   1.178  +	movw	%sp,%bp
   1.179  +
   1.180 @@ -373,9 +365,8 @@
   1.181  +
   1.182  +	cmpb	$5, %cl
   1.183  +	jae	no_reg			/* see if register name is needed */
   1.184 - 
   1.185 - 	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.186 -+	movw	$0xe05+0x41-1, %ax
   1.187 ++
   1.188 ++	movb	$0x5+0x41-1, %al
   1.189  +	subb	%cl,%al
   1.190  +	int	$0x10
   1.191  +
   1.192 @@ -389,49 +380,45 @@
   1.193  +	addw	$2, %bp			/* next register */
   1.194  +	call	print_hex		/* print it */
   1.195  +	movb	$0x20, %al		/* print a space */
   1.196 -+	int	$0x10
   1.197 + 	int	$0x10
   1.198  +	popw	%cx
   1.199  +	loop	print_loop
   1.200 -+	call	print_nl		/* nl for readability */
   1.201 -+	ret
   1.202 ++					/* nl for readability */
   1.203 ++print_nl: 
   1.204 ++	movb	$0xd, %al		/* CR */
   1.205 ++	call	print_char
   1.206 ++	movb	$0xa, %al		/* LF */
   1.207 ++	jmp	print_char
   1.208 ++
   1.209  +
   1.210  +print_str: 
   1.211 -+	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.212 - 	movb	$0x0e, %ah		/* write char, tty mode */
   1.213 - prloop: 
   1.214 - 	lodsb
   1.215 - 	int	$0x10
   1.216 ++prloop: 
   1.217 ++	lodsb
   1.218 ++	call	print_char
   1.219   	loop	prloop
   1.220  -freeze: jmp	freeze
   1.221  +	ret
   1.222  +
   1.223 -+print_nl: 
   1.224 -+	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.225 -+	movw	$0xe0d, %ax		/* CR */
   1.226 -+	int	$0x10
   1.227 -+	movb	$0xa, %al		/* LF */
   1.228 -+	int	$0x10
   1.229 -+	ret
   1.230 -+
   1.231  +/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
   1.232  +
   1.233  +print_hex: 
   1.234  +	movw	(%bp),%dx		/* load word into dx */
   1.235  +	movb	$4, %cl
   1.236 -+	movb	$0x0e, %ah		/* write char, tty mode */
   1.237 -+	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.238 -+	call	print_digit2
   1.239 -+print_digit2: 
   1.240 ++	call	print_2digits
   1.241 ++print_2digits: 
   1.242  +	call	print_digit
   1.243  +/* fall through */
   1.244  +print_digit: 
   1.245 -+	rol	%cl,%dx			/* rotate so that lowest 4 bits are used */
   1.246 ++	rol	%cl,%dx			/* rotate to use lowest 4 bits */
   1.247  +	movb	$0x0f, %al		/* mask for nybble */
   1.248  +	andb	%dl,%al
   1.249 -+	addb	$0x90, %al		/* convert al to ascii hex (four instructions) */
   1.250 -+	daa
   1.251 ++	addb	$0x90, %al		/* convert al to ascii hex */
   1.252 ++	daa				/* (four instructions) */
   1.253  +	adcb	$0x40, %al
   1.254  +	daa
   1.255 ++print_char:
   1.256 ++	movb	$0x0e, %ah		/* write char, tty mode */
   1.257 ++	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.258  +	int	$0x10
   1.259  +	ret
   1.260  +
   1.261 @@ -448,11 +435,425 @@
   1.262  -why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
   1.263  -why_end: 
   1.264  +disksizes: 
   1.265 -+	.byte 36,18,15,9
   1.266 ++	.byte 36,18,15,9,0
   1.267   
   1.268  +msg1: 
   1.269 -+	.ascii "Loading ROM"
   1.270 ++	.ascii "Loading ROM image"
   1.271  +msg1end: 
   1.272   
   1.273   	.org	497
   1.274   setup_sects: 
   1.275 +@@ -117,15 +402,22 @@
   1.276 + 	whose entry point is SYSSEG:0.
   1.277 + */
   1.278 + setup_code: 
   1.279 +-	pushl	$0		/* No parameters to preserve for exit path */
   1.280 +-	pushw	$0		/* Use prefix exit path mechanism */
   1.281 ++	movw	$(SYSSEG-(PREFIXSIZE/16)), %ax
   1.282 + 	/* Etherboot expects to be contiguous in memory once loaded.
   1.283 + 	 * LILO doesn't do this, but since we don't need any
   1.284 + 	 * information that's left in the prefix, it doesn't matter:
   1.285 + 	 * we just have to ensure that %cs:0000 is where the start of
   1.286 + 	 * the Etherboot image *would* be.
   1.287 + 	 */
   1.288 +-	ljmp	$(SYSSEG-(PREFIXSIZE/16)), $_start
   1.289 ++go_setup_code: 
   1.290 ++	xorw	%cx, %cx
   1.291 ++	pushw	%cx
   1.292 ++	pushw	%cx		/* No parameters to preserve for exit path */
   1.293 ++	pushw	%cx		/* Use prefix exit path mechanism */
   1.294 ++	pushw	%ax
   1.295 ++	pushw	$_start
   1.296 ++	/* Calculated lcall to _start with %cs:0000 = image start */
   1.297 ++	lret
   1.298 + 
   1.299 + 	.section ".text16", "ax", @progbits
   1.300 + 	.globl	prefix_exit
   1.301 +
   1.302 +--- etherboot-5.4.3/src/arch/i386/prefix/bImageprefix.S
   1.303 ++++ etherboot-5.4.3/src/arch/i386/prefix/bImageprefix.S
   1.304 +@@ -82,6 +82,14 @@
   1.305 + #define SIG1	0xAA55
   1.306 + #define SIG2	0x5A5A
   1.307 + 
   1.308 ++/* SYS_SIZE is the number of clicks (16 bytes) to be loaded.  For Etherboot
   1.309 ++ * purposes, we need to load everything but the boot sector itself, i.e. 32
   1.310 ++ * clicks less than the size of the entire (verbatim) image.  The image size
   1.311 ++ * is practically limited only by the available base memory size.
   1.312 ++ */
   1.313 ++.globl	SYSSIZE
   1.314 ++.equ	SYSSIZE, _verbatim_size_pgh - 32
   1.315 ++
   1.316 + 	.text
   1.317 + 	.code16
   1.318 + 	.arch i386
   1.319 +@@ -90,40 +98,349 @@
   1.320 + 	.globl	_prefix
   1.321 + _prefix:
   1.322 + 
   1.323 +-/* 
   1.324 +-	This is a minimal boot sector.	If anyone tries to execute it (e.g., if
   1.325 +-	a .lilo file is dd'ed to a floppy), print an error message. 
   1.326 +-*/
   1.327 ++	call	here
   1.328 ++here:
   1.329 ++	pop	%ax
   1.330 ++	cmpw	$0x103, %ax		/* COM entry point is cs:0x100 */
   1.331 ++	jne	bootsector
   1.332 ++
   1.333 ++/* We need a real mode stack that won't be stomped on by Etherboot
   1.334 ++   which starts at 0x20000. Choose something that's sufficiently high,
   1.335 ++   but not in DOC territory. Note that we couldn't do this in a real
   1.336 ++   .com program since stack variables are in the same segment as the
   1.337 ++   code and data, but this isn't really a .com program, it just looks
   1.338 ++   like one to make DOS load it into memory. It still has the 64kB
   1.339 ++   limitation of .com files though. */
   1.340 ++#define STACK_SEG	0x7000
   1.341 ++#define STACK_SIZE	0x4000
   1.342 ++	/* Set up temporary stack */ 
   1.343 ++	movw	$STACK_SEG, %ax
   1.344 ++	movw	%ax, %ss
   1.345 ++	movw	$STACK_SIZE, %sp
   1.346 ++
   1.347 ++	/* Calculate segment address of image start */
   1.348 ++	pushw	%cs
   1.349 ++	popw	%ax
   1.350 ++	addw	$(0x100/16), %ax
   1.351 ++	jmp	go_setup_code
   1.352 + 
   1.353 +-bootsector: 
   1.354 +-	jmp	$BOOTSEG, $go - _prefix	/* reload cs:ip to match relocation addr */
   1.355 ++bootsector:
   1.356 ++	jmp	$BOOTSEG, $go		/* reload cs:ip to match relocation addr */
   1.357 + go: 
   1.358 +-	movw	$0x2000, %di		/*  0x2000 is arbitrary value >= length
   1.359 +-					    of bootsect + room for stack */
   1.360 ++	movw	$0x2000-12, %di		/* 0x2000 is arbitrary value >= length */
   1.361 ++					/* of bootsect + room for stack + 12 for */
   1.362 ++					/* saved disk parm block */
   1.363 + 
   1.364 + 	movw	$BOOTSEG, %ax
   1.365 + 	movw	%ax,%ds
   1.366 + 	movw	%ax,%es
   1.367 +-
   1.368 +-	cli
   1.369 +-	movw	%ax, %ss		/* put stack at BOOTSEG:0x2000. */
   1.370 ++	movw	%ax,%ss			/* put stack at initial position */
   1.371 + 	movw	%di,%sp
   1.372 +-	sti
   1.373 + 
   1.374 +-	movw	$why_end-why, %cx
   1.375 +-	movw	$why - _prefix, %si
   1.376 ++/* Many BIOS's default disk parameter tables will not recognize multi-sector
   1.377 ++ * reads beyond the maximum sector number specified in the default diskette
   1.378 ++ * parameter tables - this may mean 7 sectors in some cases.
   1.379 ++ *
   1.380 ++ * Since single sector reads are slow and out of the question, we must take care
   1.381 ++ * of this by creating new parameter tables (for the first disk) in RAM.  We
   1.382 ++ * will set the maximum sector count to 36 - the most we will encounter on an
   1.383 ++ * ED 2.88.  High doesn't hurt.	Low does.
   1.384 ++ *
   1.385 ++ * Segments are as follows: ds=es=ss=cs - BOOTSEG
   1.386 ++ */
   1.387 ++
   1.388 ++	xorw	%cx,%cx
   1.389 ++	movw	%cx,%es			/* access segment 0 */
   1.390 ++	movw	$0x78, %bx		/* 0:bx is parameter table address */
   1.391 ++	pushw	%ds			/* save ds */
   1.392 ++/* 0:bx is parameter table address */
   1.393 ++	ldsw	%es:(%bx),%si		/* loads ds and si */
   1.394 ++
   1.395 ++	movw	%ax,%es			/* ax is BOOTSECT (loaded above) */
   1.396 ++	movb	$6, %cl			/* copy 12 bytes */
   1.397 ++	cld
   1.398 ++	pushw	%di			/* keep a copy for later */
   1.399 ++	rep
   1.400 ++	movsw				/* ds:si is source, es:di is dest */
   1.401 ++	popw	%di
   1.402 + 
   1.403 +-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.404 +-	movb	$0x0e, %ah		/* write char, tty mode */
   1.405 +-prloop: 
   1.406 ++	movb	$36,%es:4(%di)
   1.407 ++
   1.408 ++	movw	%cx,%ds			/* access segment 0 */
   1.409 ++	xchgw	%di,(%bx)
   1.410 ++	movw	%es,%si
   1.411 ++	xchgw	%si,2(%bx)
   1.412 ++	popw	%ds			/* restore ds */
   1.413 ++	movw	%di, dpoff		/* save old parameters */
   1.414 ++	movw	%si, dpseg		/* to restore just before finishing */
   1.415 ++	pushw	%ds
   1.416 ++	popw	%es			/* reload es */
   1.417 ++
   1.418 ++/* Note that es is already set up.  Also cx is 0 from rep movsw above. */
   1.419 ++
   1.420 ++	xorb	%ah,%ah			/* reset FDC */
   1.421 ++	xorb	%dl,%dl
   1.422 ++	int	$0x13
   1.423 ++
   1.424 ++/* Get disk drive parameters, specifically number of sectors/track.
   1.425 ++ *
   1.426 ++ * It seems that there is no BIOS call to get the number of sectors.  Guess
   1.427 ++ * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
   1.428 ++ * 15 if sector 15 can be read.	Otherwise guess 9.
   1.429 ++ */
   1.430 ++
   1.431 ++	movw	$disksizes, %si		/* table of sizes to try */
   1.432 ++
   1.433 ++probe_loop: 
   1.434 + 	lodsb
   1.435 ++	orb	%al, %al
   1.436 ++	je	got_sectors		/* if all else fails, try 9 */
   1.437 ++	cbtw				/* extend to word */
   1.438 ++	movw	%ax, sectors
   1.439 ++	xchgw	%cx,%ax			/* cx = track and sector */
   1.440 ++	xorw	%dx,%dx			/* drive 0, head 0 */
   1.441 ++	movw	$0x0200, %bx		/* address after boot sector */
   1.442 ++					/*   (512 bytes from origin, es = cs) */
   1.443 ++	movw	$0x0201, %ax		/* service 2, 1 sector */
   1.444 ++	int	$0x13
   1.445 ++	jc	probe_loop		/* try next value */
   1.446 ++
   1.447 ++got_sectors: 
   1.448 ++	movw	$msg1end-msg1, %cx
   1.449 ++	movw	$msg1, %si
   1.450 ++	call	print_str
   1.451 ++
   1.452 ++/* ok, we've written the Loading... message, now we want to load the system */
   1.453 ++
   1.454 ++	pushw	%es			/* = ds */
   1.455 ++	movw	$SYSSEG, %ax
   1.456 ++	movw	%ax,%es			/* segment of SYSSEG<<4 */
   1.457 ++	pushw	%es
   1.458 ++	call	read_it
   1.459 ++
   1.460 ++/* This turns off the floppy drive motor, so that we enter the kernel in a
   1.461 ++ * known state, and don't have to worry about it later.
   1.462 ++ */
   1.463 ++	movw	$0x3f2, %dx
   1.464 ++	xorb	%al,%al
   1.465 ++	outb	%al,%dx
   1.466 ++
   1.467 ++	call	print_nl
   1.468 ++	pop	%es			/* = SYSSEG */
   1.469 ++	pop	%es			/* balance push/pop es */
   1.470 ++sigok: 
   1.471 ++
   1.472 ++/* Restore original disk parameters */
   1.473 ++	movw	$0x78, %bx
   1.474 ++	movw	dpoff, %di
   1.475 ++	movw	dpseg, %si
   1.476 ++	xorw	%ax,%ax
   1.477 ++	movw	%ax,%ds
   1.478 ++	movw	%di,(%bx)
   1.479 ++	movw	%si,2(%bx)
   1.480 ++
   1.481 ++/* after that (everything loaded), we call to the .ROM file loaded. */
   1.482 ++
   1.483 ++	movw	$SYSSEG, %ax
   1.484 ++go_setup_code: 
   1.485 ++	xorw	%cx, %cx
   1.486 ++	pushw	%cx
   1.487 ++	pushw	%cx		/* No parameters to preserve for exit path */
   1.488 ++	pushw	%cx		/* Use prefix exit path mechanism */
   1.489 ++	pushw	%ax
   1.490 ++	pushw	$_start
   1.491 ++	/* Calculated lcall to _start with %cs:0000 = image start */
   1.492 ++	lret
   1.493 ++
   1.494 ++/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
   1.495 ++ * boundaries are crossed. We try to load it as fast as possible, loading whole
   1.496 ++ * tracks whenever we can.
   1.497 ++ *
   1.498 ++ * in:	es - starting address segment (normally SYSSEG)
   1.499 ++ */
   1.500 ++read_it: 
   1.501 ++	movw	$0,sread		/* read whole image incl boot sector */
   1.502 ++	movw	%es,%ax
   1.503 ++	testw	$0x0fff, %ax
   1.504 ++die:	jne	die			/* es must be at 64kB boundary */
   1.505 ++	xorw	%bx,%bx			/* bx is starting address within segment */
   1.506 ++rp_read: 
   1.507 ++	movw	%es,%ax
   1.508 ++	movw	%bx,%dx
   1.509 ++	movb	$4, %cl
   1.510 ++	shrw	%cl,%dx			/* bx is always divisible by 16 */
   1.511 ++	addw	%dx,%ax
   1.512 ++	cmpw	$SYSSEG+SYSSIZE, %ax	/* have we loaded all yet? */
   1.513 ++	jb	ok1_read
   1.514 ++	ret
   1.515 ++ok1_read: 
   1.516 ++	movw	sectors, %ax
   1.517 ++	subw	sread, %ax
   1.518 ++	movw	%ax,%cx
   1.519 ++	shlw	$9, %cx			/* 80186 opcode */
   1.520 ++	addw	%bx,%cx
   1.521 ++	jnc	ok2_read
   1.522 ++	je	ok2_read
   1.523 ++	xorw	%ax,%ax
   1.524 ++	subw	%bx,%ax
   1.525 ++	shrw	$9, %ax			/* 80186 opcode */
   1.526 ++ok2_read: 
   1.527 ++	call	read_track
   1.528 ++	movw	%ax,%cx
   1.529 ++	addw	sread, %ax
   1.530 ++	cmpw	sectors, %ax
   1.531 ++	jne	ok3_read
   1.532 ++	movw	$1, %ax
   1.533 ++	subw	head, %ax
   1.534 ++	jne	ok4_read
   1.535 ++	incw	track
   1.536 ++ok4_read: 
   1.537 ++	movw	%ax, head
   1.538 ++	xorw	%ax,%ax
   1.539 ++ok3_read: 
   1.540 ++	movw	%ax, sread
   1.541 ++	shlw	$9, %cx			/* 80186 opcode */
   1.542 ++	addw	%cx,%bx
   1.543 ++	jnc	rp_read
   1.544 ++	movw	%es,%ax
   1.545 ++	addb	$0x10, %ah
   1.546 ++	movw	%ax,%es
   1.547 ++	xorw	%bx,%bx
   1.548 ++	jmp	rp_read
   1.549 ++
   1.550 ++read_track: 
   1.551 ++	pusha				/* 80186 opcode */
   1.552 ++	pushw	%ax
   1.553 ++	pushw	%bx
   1.554 ++	pushw	%bp			/* just in case the BIOS is buggy */
   1.555 ++	movb	$0x2e, %al		/* 0x2e = . */
   1.556 ++	call	print_char
   1.557 ++	popw	%bp
   1.558 ++	popw	%bx
   1.559 ++	popw	%ax
   1.560 ++
   1.561 ++	movw	sread, %cx
   1.562 ++	incw	%cx
   1.563 ++	movb	track, %ch
   1.564 ++	movw	$0x0100, %dx
   1.565 ++	andb	head, %dh
   1.566 ++	movb	$2, %ah
   1.567 ++
   1.568 ++	pushw	%dx			/* save for error dump */
   1.569 ++	pushw	%cx
   1.570 ++	pushw	%bx
   1.571 ++	pushw	%ax
   1.572 ++
   1.573 ++	int	$0x13
   1.574 ++	jc	bad_rt
   1.575 ++	addw	$8, %sp
   1.576 ++	popa				/* 80186 opcode */
   1.577 ++	ret
   1.578 ++
   1.579 ++bad_rt: pushw	%ax			/* save error code */
   1.580 ++	call	print_all		/* ah = error, al = read */
   1.581 ++
   1.582 ++	xorb	%ah,%ah
   1.583 ++	xorb	%dl,%dl
   1.584 ++	int	$0x13
   1.585 ++
   1.586 ++	addw	$10, %sp
   1.587 ++	popa				/* 80186 opcode */
   1.588 ++	jmp	read_track
   1.589 ++
   1.590 ++/* print_all is for debugging purposes.	It will print out all of the registers.
   1.591 ++ * The assumption is that this is called from a routine, with a stack frame like
   1.592 ++ *	dx
   1.593 ++ *	cx
   1.594 ++ *	bx
   1.595 ++ *	ax
   1.596 ++ *	error
   1.597 ++ *	ret <- sp
   1.598 ++ */
   1.599 ++
   1.600 ++print_all: 
   1.601 ++	call	print_nl		/* nl for readability */
   1.602 ++					/* print_nl update ah and bx */
   1.603 ++	movw	$5, %cx			/* error code + 4 registers */
   1.604 ++	movw	%sp,%bp
   1.605 ++
   1.606 ++print_loop: 
   1.607 ++	pushw	%cx			/* save count left */
   1.608 ++
   1.609 ++	cmpb	$5, %cl
   1.610 ++	jae	no_reg			/* see if register name is needed */
   1.611 ++
   1.612 ++	movb	$0x5+0x41-1, %al
   1.613 ++	subb	%cl,%al
   1.614 + 	int	$0x10
   1.615 ++
   1.616 ++	movb	$0x58, %al		/* 'X' */
   1.617 ++	int	$0x10
   1.618 ++
   1.619 ++	movb	$0x3A, %al		/* ':' */
   1.620 ++	int	$0x10
   1.621 ++
   1.622 ++no_reg: 
   1.623 ++	addw	$2, %bp			/* next register */
   1.624 ++	call	print_hex		/* print it */
   1.625 ++	movb	$0x20, %al		/* print a space */
   1.626 ++	int	$0x10
   1.627 ++	popw	%cx
   1.628 ++	loop	print_loop
   1.629 ++					/* nl for readability */
   1.630 ++print_nl: 
   1.631 ++	movb	$0xd, %al		/* CR */
   1.632 ++	call	print_char
   1.633 ++	movb	$0xa, %al		/* LF */
   1.634 ++	jmp	print_char
   1.635 ++
   1.636 ++
   1.637 ++print_str: 
   1.638 ++prloop: 
   1.639 ++	lodsb
   1.640 ++	call	print_char
   1.641 + 	loop	prloop
   1.642 +-freeze: jmp	freeze
   1.643 ++	ret
   1.644 + 
   1.645 +-why:	.ascii	"This image cannot be loaded from a floppy disk.\r\n"
   1.646 +-why_end: 
   1.647 ++/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
   1.648 ++
   1.649 ++print_hex: 
   1.650 ++	movw	(%bp),%dx		/* load word into dx */
   1.651 ++	movb	$4, %cl
   1.652 ++	call	print_2digits
   1.653 ++print_2digits: 
   1.654 ++	call	print_digit
   1.655 ++/* fall through */
   1.656 ++print_digit: 
   1.657 ++	rol	%cl,%dx			/* rotate to use lowest 4 bits */
   1.658 ++	movb	$0x0f, %al		/* mask for nybble */
   1.659 ++	andb	%dl,%al
   1.660 ++	addb	$0x90, %al		/* convert al to ascii hex */
   1.661 ++	daa				/* (four instructions) */
   1.662 ++	adcb	$0x40, %al
   1.663 ++	daa
   1.664 ++print_char:
   1.665 ++	movb	$0x0e, %ah		/* write char, tty mode */
   1.666 ++	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
   1.667 ++	int	$0x10
   1.668 ++	ret
   1.669 + 
   1.670 ++sread:	.word 0				/* sectors read of current track */
   1.671 ++head:	.word 0				/* current head */
   1.672 ++track:	.word 0				/* current track */
   1.673 ++
   1.674 ++sectors: 
   1.675 ++	.word 0
   1.676 ++
   1.677 ++dpseg:	.word 0
   1.678 ++dpoff:	.word 0
   1.679 ++
   1.680 ++disksizes: 
   1.681 ++	.byte 36,18,15,9,0
   1.682 ++
   1.683 ++msg1: 
   1.684 ++	.ascii "Loading ROM image"
   1.685 ++msg1end: 
   1.686 + 
   1.687 + 	.org	497
   1.688 + setup_sects: