wok diff etherboot/stuff/etherboot-prefix.u @ rev 16216
Add fbcat
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Mon Mar 31 16:32:29 2014 +0000 (2014-03-31) |
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 Mon Mar 31 16:32:29 2014 +0000 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: