1 2 ;----------------------------------------------------------------------------- 3 ; ElTorito.asm 4 ; 5 ; El Torito Bootable CD-ROM driver which does not reset the CD-ROM drive upon 6 ; loading, but instead accesses the drive through BIOS system calls 7 ; 8 ; MIT License 9 ; 10 ; (c) 2000 by Gary Tong 11 ; (c) 2001-2009 by Bart Lagerweij 12 ; 13 ; Permission is hereby granted, free of charge, to any person obtaining a copy 14 ; of this software and associated documentation files (the "Software"), to deal 15 ; in the Software without restriction, including without limitation the rights 16 ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 ; copies of the Software, and to permit persons to whom the Software is 18 ; furnished to do so, subject to the following conditions: 19 ; 20 ; The above copyright notice and this permission notice shall be included in 21 ; all copies or substantial portions of the Software. 22 ; 23 ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 ; THE SOFTWARE. 30 ; 31 ;----------------------------------------------------------------------------- 32 33 ; To assemble and link, use these commands with NASM 2.x: 34 ; nasm -Ox -f bin -o eltorito.sys eltorito.asm 35 36 ; To enable Trace markers uncomment the line below 37 ; DEBUG_TRACERS=1 38 39 ; To enable debug info uncomment the line below 40 ; DEBUG=1 41 42 %ifdef DEBUG_TRACERS 43 %macro TRACER 1 44 call debug_tracer 45 db %1 46 %endmacro 47 %else 48 %macro TRACER 1 49 %endmacro 50 %endif ; DEBUG_TRACERS 51 52 %define Ver '1.5' 53 %define CR 0DH, 0Ah 54 RPolyH equ 0EDB8h 55 RPolyL equ 08320h 56 57 section .text align=16 58 org 0 59 60 ;============================================================================= 61 62 Cdrom: 63 64 00000000 FFFFFFFF NextDriver dd -1 ;-+ 65 00000004 00C8 Attributes dw 0C800h ; | 66 00000006 [2601] Pointers dw Strategy ; | 67 00000008 [3101] dw Commands ; | MSCDEX requires this 68 0000000A 454C544F5249544F DeviceName db 'ELTORITO' ; | data in these locations 69 00000012 0000 dw 0 ; | 70 00000014 00 DriveLetter db 0 ; | 71 00000015 01 NumUnitsSupp db 1 ;-+ 72 73 00000016 456C2D546F7269746F- DriverName db 'El-Torito CD-ROM Device Driver',0 73 0000001F 2043442D524F4D2044- 73 00000028 657669636520447269- 73 00000031 76657200 74 00000035 00 align 4, db 0 75 00000038 00000000 ReqHdrLoc dd 0 76 0000003C 00000000 XferAddr dd 0 77 00000040 FFFFFFFF Checksum dd -1 78 00000044 00 DriveNumber db 0 79 00000045 00 ReadBytes db 0 ;0 --> 2048 bytes/sector 80 ;1 --> 1024 bytes/sector 81 ;2 --> 512 bytes/sector 82 83 00000046 [F10B] Routines dw Init ;Init ;0 84 00000048 [7701] dw Unsupported ;MediaCheck ;1 85 0000004A [7701] dw Unsupported ;BuildBPB ;2 86 0000004C [7B01] dw IoctlInput ;IoctlInput ;3 87 0000004E [7701] dw Unsupported ;Input ;4 88 00000050 [7701] dw Unsupported ;NonDesInput ;5 89 00000052 [7701] dw Unsupported ;InputStatus ;6 90 00000054 [7701] dw Unsupported ;InputFlush ;7 91 00000056 [7701] dw Unsupported ;Output ;8 92 00000058 [7701] dw Unsupported ;OutputVerify ;9 93 0000005A [7701] dw Unsupported ;OutputStatus ;10 94 0000005C [7701] dw Unsupported ;OutputFlush ;11 95 0000005E [B602] dw IoctlOutput ;IoctlOutput ;12 96 00000060 [D002] dw DoNothing ;DeviceOpen ;13 97 00000062 [D002] dw DoNothing ;DeviceClose ;14 98 00000064 [D402] dw ReadL ;ReadL ;128 99 100 00000066 [9801] IoctlICtrl dw Raddr ;Raddr ;0 101 00000068 [7701] dw Unsupported ;LocHead ;1 102 0000006A [7701] dw Unsupported ;(Reserved) ;2 103 0000006C [7701] dw Unsupported ;ErrStat ;3 104 0000006E [7701] dw Unsupported ;AudInfo ;4 105 00000070 [A501] dw DrvBytes ;DrvBytes ;5 106 00000072 [C201] dw DevStat ;DevStat ;6 107 00000074 [D101] dw SectSize ;SectSize ;7 108 00000076 [DB01] dw VolSize ;VolSize ;8 109 00000078 [F501] dw MedChng ;MedChng ;9 110 111 0000007A 00 SpecPkt times 19 db 0 ; offset 77h in 1.4 112 0000008D 00 times 13 db 0 ; unknown extra 00s in 1.4 113 114 0000009A 456C2D546F7269746F- Greeting db 'El-Torito Bootable CD-ROM Driver for Dos v',Ver,', http://www.nu2.nu/eltorito/',CR 114 000000A3 20426F6F7461626C65- 114 000000AC 2043442D524F4D2044- 114 000000B5 726976657220666F72- 114 000000BE 20446F732076312E35- 114 000000C7 2C20687474703A2F2F- 114 000000D0 7777772E6E75322E6E- 114 000000D9 752F656C746F726974- 114 000000E2 6F2F0D0A 115 000000E6 202028632920323030- db ' (c) 2000 by Gary Tong',CR 115 000000EF 302062792047617279- 115 000000F8 20546F6E670D0A 116 000000FF 202028632920323030- db ' (c) 2001-2002 by Bart Lagerweij',CR,0 116 00000108 312D32303032206279- 116 00000111 2042617274204C6167- 116 0000011A 65727765696A0D0A00 117 00000123 202000 DblSpace db ' ',0 118 119 ;============================================================================= 120 121 Strategy: 122 123 00000126 2E891E[3800] mov word [cs:ReqHdrLoc],bx 124 0000012B 2E8C06[3A00] mov word [cs:ReqHdrLoc+2],es 125 00000130 CB retf 126 127 128 ;============================================================================= 129 130 Commands: 131 132 00000131 50 push ax 133 00000132 53 push bx 134 00000133 51 push cx 135 00000134 52 push dx 136 00000135 56 push si 137 00000136 57 push di 138 00000137 55 push bp 139 ; pushad 140 00000138 1E push ds 141 00000139 06 push es 142 TRACER 'C' 143 144 0000013A FC cld ;Clear direction 145 0000013B FB sti ;Enable interrupts 146 147 0000013C 8CC8 mov ax, cs ;ds=cs 148 0000013E 8ED8 mov ds, ax 149 150 00000140 C41E[3800] les bx,[ReqHdrLoc] ;seg:offset ptr into es:bx 151 00000144 31C0 xor ax,ax 152 00000146 268A4702 mov al,[es:bx+2] ;Get Command code 153 %ifdef DEBUG 154 call print_hex8 155 %endif 156 0000014A 3C0F cmp al,15 157 0000014C 720C jb Mult2 ;If 0-14 158 0000014E 3C80 cmp al,128 159 00000150 7204 jb UnknownCmd ;If 15-127 160 00000152 3C81 cmp al,129 161 00000154 7202 jb ShiftDown ;If 128 162 00000156 B079 UnknownCmd: mov al,121 ;8 = Unsupported (Reserved) 163 00000158 2C71 ShiftDown: sub al,113 ;128 --> 15, 121 --> 8 164 0000015A D0E0 Mult2: shl al,1 ;Convert into offset (*2) 165 0000015C BF[4600] mov di,Routines 166 0000015F 01C7 add di,ax 167 00000161 FF15 call word [di] ;Execute desired command 168 00000163 0D0001 or ax,100h ;Set Return Status's Done bit 169 00000166 C51E[3800] lds bx,[ReqHdrLoc] ;seg:offset ptr into ds:bx 170 0000016A 894703 mov [bx+3],ax ;Save Status 171 172 %ifdef DEBUG 173 cmp byte [cs:buffer+2048], 96h 174 je buffer_ok 175 mov al, '!' 176 call print_char 177 jmp $ 178 buffer_ok: 179 %endif 180 181 TRACER 'c' 182 0000016D 07 pop es 183 0000016E 1F pop ds 184 ; popad 185 0000016F 5D pop bp 186 00000170 5F pop di 187 00000171 5E pop si 188 00000172 5A pop dx 189 00000173 59 pop cx 190 00000174 5B pop bx 191 00000175 58 pop ax 192 00000176 CB retf 193 194 195 ;============================================================================= 196 197 Unsupported: ;Unsupported Command 198 199 00000177 B80380 mov ax,8003h ;Set Status Error bit, 200 TRACER 'U' 201 TRACER 'C' 202 0000017A C3 retn ; Error 3 = Unknown Command 203 204 205 ;============================================================================= 206 207 IoctlInput: ;IOCTL Input Routine 208 209 0000017B 268B7F0E mov di,[es:bx+14] ;es:bx --> Request Header 210 0000017F 268E4710 mov es,[es:bx+16] ;Get Xfer Address into es:di 211 00000183 31C0 xor ax,ax ;Get Control Block Code 212 00000185 268A05 mov al,[es:di] 213 %ifdef DEBUG 214 TRACER 'I' 215 TRACER 'O' 216 call print_hex8 217 %endif 218 00000188 3C0A cmp al,10 219 0000018A 7202 jb UnkIoctlI ;If 0-9 220 0000018C B002 mov al,2 ;Map to Unsupported 221 0000018E D0E0 UnkIoctlI: shl al,1 ;Convert into offset (*2) 222 00000190 BE[6600] mov si,IoctlICtrl 223 00000193 01C6 add si,ax 224 00000195 FF14 call word [si] ;Execute desired command 225 00000197 C3 retn 226 227 228 ;============================================================================= 229 230 Raddr: ;Return Device Header Address 231 232 TRACER 'A' 233 00000198 26C745010000 mov word [es:di+1],0 234 0000019E 268C4D03 mov [es:di+3],cs 235 000001A2 31C0 xor ax, ax ;Set Return Status = success 236 TRACER 'a' 237 000001A4 C3 retn 238 239 240 ;============================================================================= 241 242 DrvBytes: ;Read Drive Bytes 243 244 TRACER 'B' 245 000001A5 57 push di ;Save original Xfer Addr 246 000001A6 83C702 add di,2 ;Point to 1st dest byte 247 000001A9 BE[9A00] mov si,Greeting ;Point to Greeting 248 000001AC A4 DrvB: movsb ;Copy over a byte 249 000001AD 803C0D cmp byte [si],13 ;Is next char a CR? 250 000001B0 75FA jne DrvB ;Loop if not 251 252 000001B2 83EF02 sub di,2 ;Get #bytes copied into ax 253 000001B5 89F8 mov ax,di 254 000001B7 5F pop di ;Retrieve original Xfer Addr 255 000001B8 29F8 sub ax,di 256 000001BA 26884501 mov byte [es:di+1],al ;and save it 257 000001BE B80000 mov ax,0 ;Set Return Status = success 258 TRACER 'b' 259 000001C1 C3 retn 260 261 262 ;============================================================================= 263 264 DevStat: ;Return Device Status 265 266 TRACER 'D' 267 000001C2 26C745010202 mov word [es:di+1],202h ;Door closed 268 000001C8 26C745030000 mov word [es:di+3],0 ;Door unlocked 269 ;Supports only cooked reading 270 ;Read only 271 ;Data read only 272 ;No interleaving 273 ;No prefetching 274 ;No audio channel manipulation 275 ;Supports both HSG and Redbook 276 ; addressing modes 277 278 000001CE 31C0 xor ax, ax ;Set Return Status = success 279 TRACER 'd' 280 000001D0 C3 retn 281 282 283 ;============================================================================= 284 285 SectSize: ;Return Sector Size 286 287 TRACER 'S' 288 000001D1 26C745020008 mov word [es:di+2],2048 289 000001D7 B80000 mov ax,0 ;Set Return Status = success 290 TRACER 's' 291 000001DA C3 retn 292 293 294 ;============================================================================= 295 296 VolSize: ;Return Volume Size 297 298 TRACER 'V' 299 000001DB E82D00 call PriVolDesc ;Get and Check Primary Volume 300 ; Descriptor 301 000001DE B80F80 mov ax,800Fh ;Assume Invalid Disk Change 302 000001E1 7211 jc VolExit ;If Read Failure 303 304 000001E3 A1[4004] mov ax,word [Buffer+80] ;Read Successful 305 000001E6 26894501 mov word [es:di+1],ax ;Copy over Volume Size 306 000001EA A1[4204] mov ax,word [Buffer+82] 307 000001ED 26894503 mov word [es:di+3],ax 308 000001F1 B80000 mov ax,0 ;Set Return Status = success 309 VolExit: 310 TRACER 'v' 311 000001F4 C3 retn 312 313 314 ;============================================================================= 315 316 MedChng: ;Return Media Changed Status 317 318 TRACER 'M' 319 000001F5 E81300 call PriVolDesc ;Get and Check Primary Volume 320 ; Descriptor 321 000001F8 26C64501FF mov byte [es:di+1],-1 ;Assume Media Changed 322 000001FD B80F80 mov ax,800Fh ; and Invalid Disk Change 323 00000200 7208 jc MedExit ;If Media Changed or Bad 324 325 00000202 26C6450101 mov byte [es:di+1],1 ;Media has not changed 326 00000207 B80000 mov ax,0 ;Set Return Status = success 327 MedExit: 328 TRACER 'm' 329 0000020A C3 retn 330 331 332 ;============================================================================= 333 334 PriVolDesc: ;Get and Check Primary Volume 335 ; Descriptor 336 TRACER 'P' 337 0000020B 8CC8 mov ax,cs ;Set ds:si --> SpecPkt 338 0000020D 8ED8 mov ds,ax 339 340 0000020F B90500 mov cx, 5 341 PriVolAgain: 342 00000212 C606[7A00]10 mov byte [SpecPkt],16 ;SpecPkt Size 343 00000217 C606[7B00]00 mov byte [SpecPkt+1],0 ;Reserved 344 0000021C C706[7C00]0100 mov word [SpecPkt+2],1 ;Transfer one 2048-byte sector 345 00000222 51 push cx 346 00000223 8A0E[4500] mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 347 00000227 D326[7C00] shl word [SpecPkt+2],cl ; bytes at a time 348 0000022B 59 pop cx 349 0000022C 8C0E[8000] mov word [SpecPkt+6],cs ;Into our Buffer 350 00000230 C706[7E00][F003] mov word [SpecPkt+4], Buffer 351 00000236 C706[8200]1000 mov word [SpecPkt+8],16 ;From CD Sector 16 352 0000023C C706[8400]0000 mov word [SpecPkt+10],0 353 00000242 C706[8600]0000 mov word [SpecPkt+12],0 354 00000248 C706[8800]0000 mov word [SpecPkt+14],0 355 356 0000024E BE[7A00] mov si, SpecPkt 357 00000251 8A16[4400] mov dl, [DriveNumber] 358 00000255 B442 mov ah, 42h ;Extended Read 359 00000257 CD13 int 13h 360 00000259 7304 jnc PriVolPass ;If success 361 362 ; TRACER '1' 363 ; read error 364 0000025B E2B5 loop PriVolAgain 365 366 TRACER '2' 367 ; read retries exhausted 368 ; flow into below 369 0000025D EB3E jmp PriReadErr 370 371 PriVolPass: 372 0000025F BE[F003] mov si,Buffer ;Point input to Buffer 373 00000262 B8FFFF mov ax,-1 ;Init Checksum registers 374 00000265 89C3 mov bx,ax ; bx,ax = 0FFFFFFFFh 375 00000267 7241 jc PriNew ;If Read Failure 376 377 00000269 57 push di ;Read Successful, 378 ; so Calculate Checksum 379 0000026A BF0004 mov di,1024 ;Init Word counter 380 0000026D 2E8B14 PriWord: mov dx,[cs:si] ;Grab next word from buffer 381 00000270 B91000 mov cx,16 ;Init bit counter 382 00000273 D1EA PriBit: shr dx,1 ;Shift everything right 1 bit 383 00000275 D1DB rcr bx,1 384 00000277 D1D8 rcr ax,1 385 00000279 7307 jnc NoMult ;If a zero shifted out 386 387 0000027B 81F3B8ED xor bx,RPolyH ;A one shifted out, so XOR 388 0000027F 352083 xor ax,RPolyL ; Checksum with RPoly 389 NoMult: 390 00000282 E2EF loop PriBit 391 392 00000284 83C602 add si,2 ;Inc Word Pointer 393 00000287 4F dec di 394 00000288 77E3 ja PriWord 395 TRACER '3' 396 397 0000028A 5F pop di ;Checksum calculation complete 398 0000028B 3B1E[4200] cmp bx,[Checksum+2] ;Has Checksum changed? 399 0000028F 7519 jne PriNew ;If Checksum Changed 400 401 00000291 3B06[4000] cmp ax,[Checksum] 402 00000295 7513 jne PriNew ;If Checksum Changed 403 404 00000297 F8 clc ;Checksum not changed, CF=0 405 00000298 B80000 mov ax,0 ;Status = success 406 0000029B EB18 jmp PriOld 407 408 PriReadErr: 409 0000029D 891E[4200] mov WORD [Checksum+2],bx ;Save New Checksum 410 000002A1 A3[4000] mov [Checksum],ax ; or 0FFFFFFFFh if bad read 411 000002A4 F9 stc ;Checksum change, CF=1 412 000002A5 B80B80 mov ax, 800bh ;Status = read fault 413 000002A8 EB0B jmp PriOld 414 415 000002AA 891E[4200] PriNew: mov WORD [Checksum+2],bx ;Save New Checksum 416 000002AE A3[4000] mov [Checksum],ax ; or 0FFFFFFFFh if bad read 417 000002B1 F9 stc ;Checksum Changed, CF=1 418 000002B2 B80F80 mov ax,800Fh ;Status = Invalid Media Change 419 PriOld: 420 TRACER 'p' 421 000002B5 C3 retn 422 423 424 ;============================================================================= 425 426 IoctlOutput: ;IOCTL Output Routine 427 428 TRACER 'O' 429 000002B6 268B7F0E mov di,[es:bx+14] ;es:bx --> Request Header 430 000002BA 268E4710 mov es,[es:bx+16] ;Get Xfer Address into es:di 431 000002BE 31C0 xor ax,ax ;Get Control Block Code 432 000002C0 268A05 mov al,[es:di] 433 000002C3 3C02 cmp al,2 434 000002C5 7505 jne UnkIoctlO ;If not 2 (ResetDrv) 435 000002C7 E80600 call DoNothing ;Reset Drive 436 000002CA EB03 jmp IoctlODone 437 UnkIoctlO: 438 000002CC E8A8FE call Unsupported ;Unsupported command 439 IoctlODone: 440 TRACER 'o' 441 000002CF C3 retn 442 443 444 ;============================================================================= 445 446 DoNothing: ;Do Nothing Command 447 448 000002D0 B80000 mov ax,0 ;Set Return Status = success 449 000002D3 C3 retn 450 451 452 ;============================================================================= 453 454 ReadL: ;Read Long Command 455 456 TRACER 'R' 457 000002D4 8CC8 mov ax,cs ;Set ds=cs 458 000002D6 8ED8 mov ds,ax 459 ;es:bx --> Request Header 460 000002D8 26807F1800 cmp byte [es:bx+24],0 ;Check Data Read Mode 461 000002DD 7507 jne ReadLErr ;If Cooked Mode 462 463 000002DF 26807F0D02 cmp byte [es:bx+13],2 ;Check Addressing Mode 464 000002E4 7206 jb ReadLOK ;If HSG or Redbook Mode 465 466 ReadLErr: 467 TRACER '8' 468 000002E6 B80380 mov ax,8003h ;Set Return Status = Unknown 469 000002E9 E98D00 jmp ReadLExit ; Command Error and exit 470 471 ReadLOK: 472 000002EC 268B4714 mov ax,[es:bx+20] ;Get Starting Sector Number, 473 000002F0 268B5716 mov dx,[es:bx+22] ; Assume HSG Addressing Mode 474 000002F4 26807F0D00 cmp byte [es:bx+13],0 ;Check Addressing Mode again 475 000002F9 7422 je ReadLHSG ;If HSG Addressing Mode 476 477 TRACER '7' 478 ;Using Redbook Addressing Mode. Convert to HSG format 479 000002FB 88D0 mov al,dl ;Get Minutes 480 000002FD B23C mov dl,60 481 000002FF F6E2 mul dl ;ax = Minutes * 60 482 00000301 26024715 add al,byte [es:bx+21] ;Add in Seconds 483 00000305 80D400 adc ah,0 484 00000308 BA4B00 mov dx,75 ;dx:ax = 485 0000030B F7E2 mul dx ; ((Min * 60) + Sec) * 75 486 0000030D 26024714 add al,byte [es:bx+20] ;Add in Frames 487 00000311 80D400 adc ah,0 488 00000314 83D200 adc dx,0 489 00000317 2D9600 sub ax,150 ;Subtract 2-Second offset 490 0000031A 83DA00 sbb dx,0 ;dx:ax = HSG Starting Sector 491 492 ReadLHSG: 493 0000031D A3[8200] mov word [SpecPkt+8], ax ;Store Starting 494 00000320 8916[8400] mov word [SpecPkt+10], dx ; Sector Number 495 00000324 C706[8600]0000 mov word [SpecPkt+12], 0 ; (HSG Format) 496 0000032A C706[8800]0000 mov word [SpecPkt+14], 0 497 498 00000330 268B470E mov ax,[es:bx+14] ;Get Transfer Address 499 00000334 A3[7E00] mov word [SpecPkt+4],ax 500 00000337 268B4710 mov ax,[es:bx+16] 501 0000033B A3[8000] mov word [SpecPkt+6],ax 502 503 0000033E C606[7A00]10 mov byte [SpecPkt],16 ;Size of Disk Address Packet 504 00000343 C606[7B00]00 mov byte [SpecPkt+1],0 ;Reserved 505 506 00000348 B90500 mov cx, 5 507 ReadLAgain: 508 0000034B 268B4712 mov ax,[es:bx+18] ;Get number of sectors to read 509 0000034F A3[7C00] mov word [SpecPkt+2],ax 510 00000352 3DFF3F cmp ax, 3FFFh ;Too large? 511 00000355 771F ja ReadLBad ;If yes 512 513 00000357 51 push cx 514 00000358 8A0E[4500] mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 515 0000035C D326[7C00] shl word [SpecPkt+2],cl ; bytes at a time 516 00000360 59 pop cx 517 518 %ifdef DEBUG 519 push ax 520 push cx 521 push si 522 mov cx, 16 523 mov si,SpecPkt 524 ReadDump: mov al, ' ' 525 call print_char 526 mov al, byte [si] ;Hexdump a SpecPkt byte 527 call print_hex8 528 inc si ;Point to next byte 529 loop ReadDump 530 pop si 531 pop cx 532 pop ax 533 %endif 534 00000361 BE[7A00] mov si,SpecPkt 535 00000364 8A16[4400] mov dl,[DriveNumber] 536 00000368 B442 mov ah,42h ;Extended Read 537 0000036A CD13 int 13h 538 0000036C 7304 jnc ReadLGd ;If success 539 540 ;hang: 541 ; jmp hang 542 ; TRACER '1' 543 0000036E E2DB loop ReadLAgain 544 TRACER '2' 545 00000370 EB04 jmp short ReadLBad 546 ReadLGd: 547 TRACER '3' 548 00000372 31C0 xor ax, ax ;Status 0 = success 549 00000374 EB03 jmp short ReadLExit 550 551 ReadLBad: 552 TRACER '9' 553 00000376 B80B80 mov ax, 800Bh ;Set Read Fault Error 554 ; flow into ReadLExit 555 ReadLExit: 556 TRACER 'r' 557 00000379 C3 retn 558 559 560 561 %ifdef DEBUG_TRACERS 562 debug_tracer: pushad 563 pushfd 564 565 mov al, '[' 566 mov ah,0Eh ;BIOS video teletype output 567 xor bh, bh 568 int 10h ;Print it 569 570 mov bp,sp 571 mov bx,[bp+9*4] ; Get return address 572 mov al,[cs:bx] ; Get data byte 573 inc word [bp+9*4] ; Return to after data byte 574 575 mov ah,0Eh ;BIOS video teletype output 576 xor bh, bh 577 int 10h ;Print it 578 579 mov al, ']' 580 mov ah,0Eh ;BIOS video teletype output 581 xor bh, bh 582 int 10h ;Print it 583 584 popfd 585 popad 586 retn 587 %endif 588 589 ;----------------------------------------------------------------------------- 590 ; PRINT_HEX4 591 ;----------------------------------------------------------------------------- 592 ; print a 4 bits integer in hex 593 ; 594 ; Input: 595 ; AL - 4 bits integer to print (low) 596 ; 597 ; Output: None 598 ; 599 ; Registers destroyed: None 600 ; 601 print_hex4: 602 603 0000037A 50 push ax 604 0000037B 240F and al, 0fh ; we only need the first nibble 605 0000037D 3C0A cmp al, 10 606 0000037F 7304 jae hex_A_F 607 00000381 0430 add al, '0' 608 00000383 EB02 jmp hex_0_9 609 hex_A_F: 610 00000385 0437 add al, 'A'-10 611 hex_0_9: 612 00000387 E84E00 call print_char 613 0000038A 58 pop ax 614 0000038B C3 retn 615 616 617 ;----------------------------------------------------------------------------- 618 ; print_hex8 619 ;----------------------------------------------------------------------------- 620 ; print a 8 bits integer in hex 621 ; 622 ; Input: 623 ; AL - 8 bits integer to print 624 ; 625 ; Output: None 626 ; 627 ; Registers destroyed: None 628 ; 629 print_hex8: 630 631 0000038C 50 push ax 632 0000038D 53 push bx 633 634 0000038E 88C4 mov ah, al 635 00000390 C0E804 shr al, 4 636 00000393 E8E4FF call print_hex4 637 638 00000396 88E0 mov al, ah 639 00000398 240F and al, 0fh 640 0000039A E8DDFF call print_hex4 641 642 0000039D 5B pop bx 643 0000039E 58 pop ax 644 0000039F C3 retn 645 646 647 ;============================================================================= 648 ; print_hex16 - print a 16 bits integer in hex 649 ; 650 ; Input: 651 ; AX - 16 bits integer to print 652 ; 653 ; Output: None 654 ; 655 ; Registers destroyed: None 656 ;============================================================================= 657 print_hex16: 658 659 000003A0 50 push ax 660 000003A1 53 push bx 661 000003A2 51 push cx 662 663 000003A3 B90400 mov cx, 4 664 print_hex16_loop: 665 000003A6 C1C004 rol ax, 4 666 000003A9 E8CEFF call print_hex4 667 000003AC E2F8 loop print_hex16_loop 668 669 000003AE 59 pop cx 670 000003AF 5B pop bx 671 000003B0 58 pop ax 672 000003B1 C3 retn 673 674 ;============================================================================= 675 ; print_hex32 - print a 32 bits integer in hex 676 ; 677 ; Input: 678 ; EAX - 32 bits integer to print 679 ; 680 ; Output: None 681 ; 682 ; Registers destroyed: None 683 ;============================================================================= 684 print_hex32: 685 686 000003B2 6650 push eax 687 000003B4 53 push bx 688 000003B5 51 push cx 689 690 000003B6 B90800 mov cx, 8 691 print_hex32_loop: 692 000003B9 66C1C004 rol eax, 4 693 000003BD E8BAFF call print_hex4 694 000003C0 E2F7 loop print_hex32_loop 695 696 000003C2 59 pop cx 697 000003C3 5B pop bx 698 000003C4 6658 pop eax 699 000003C6 C3 retn 700 701 ;============================================================================= 702 ; print_string - print string at current cursor location 703 ; 704 ; Input: 705 ; DS:SI - ASCIIZ string to print 706 ; 707 ; Output: None 708 ; 709 ; Registers destroyed: None 710 ;============================================================================= 711 print_string: 712 000003C7 50 push ax 713 000003C8 56 push si 714 715 print_string_again: 716 000003C9 8A04 mov al, [si] 717 000003CB 08C0 or al, al 718 000003CD 7406 jz print_string_exit 719 000003CF E80600 call print_char 720 000003D2 46 inc si 721 000003D3 EBF4 jmp print_string_again 722 723 print_string_exit: 724 000003D5 5E pop si 725 000003D6 58 pop ax 726 000003D7 C3 retn 727 728 ;----------------------------------------------------------------------------- 729 ; PRINT_CHAR 730 ;----------------------------------------------------------------------------- 731 ; Print's a character at current cursor position 732 ; 733 ; Input: 734 ; AL - Character to print 735 ; 736 ; Output: None 737 ; 738 ; Registers destroyed: None 739 ; 740 print_char: 741 742 000003D8 50 push ax 743 000003D9 53 push bx 744 745 000003DA B40E mov ah,0Eh ;BIOS video teletype output 746 000003DC 30FF xor bh, bh 747 000003DE CD10 int 10h ;Print it 748 749 print_char_exit: 750 000003E0 5B pop bx 751 000003E1 58 pop ax 752 000003E2 C3 retn 753 754 755 ;============================================================================= 756 757 ;This space is used as a 2048-byte read buffer plus one test byte. 758 ;The 96h data is used for testing the number of bytes returned by an Extended 759 ; CD-ROM sector read 760 761 000003E3 00 align 16, db 0 762 000003F0 96 Buffer times 2049 db 96h 763 764 ;============================================================================= 765 766 Init: ;Initialization Routine 767 768 TRACER 'I' 769 00000BF1 8CC8 mov ax,cs ;ds=cs 770 00000BF3 8ED8 mov ds,ax 771 772 %ifdef DEBUG 773 ; print CS value (load segment) 774 call print_hex16 775 %endif 776 777 00000BF5 BE[9A00] mov si, Greeting ;Display Greeting 778 00000BF8 E8CCF7 call print_string 779 780 00000BFB B8[7701] mov ax,Unsupported ;Init is executed only once 781 00000BFE A3[4600] mov [Routines],ax 782 783 00000C01 B80054 mov ax, 5400h 784 00000C04 CD13 int 13h ; Get diskemu status 785 00000C06 721F jc FindBoot ; If CF=1 no diskemu loaded 786 787 00000C08 880E[4400] mov [DriveNumber], cl ; Store drive number 788 789 00000C0C E8E101 call keyflag 790 00000C0F 2408 and al, 8 ; alt key ? 791 00000C11 744C jz extread 792 793 00000C13 BE[F70D] mov si, DrvNumMsg ; Display "drive number=" 794 00000C16 E8AEF7 call print_string 795 00000C19 A0[4400] mov al, [DriveNumber] 796 00000C1C E86DF7 call print_hex8 797 00000C1F BE[2F0F] mov si, LineEnd ; CR/LF 798 00000C22 E8A2F7 call print_string 799 00000C25 EB38 jmp extread 800 801 ; Diskemu is not loaded 802 ; so loop to find drive number 803 ; *** start of 1.4 changes *** 804 ; ??? mov dl, 0ffh ;Start at Drive 0xff 805 ; *** FindBoot at c47 in 1.4, at c0c in 1.3 *** 806 00000C27 E89001 FindBoot: call ScanDrives ; call new helper in 1.4 807 00000C2A 7309 jnc FoundBoot ; ded*df3 808 ; mov si,offset SpecPkt ;Locate booted CD-ROM drive 809 ; mov [SpecPkt],0 ;Clear 1st byte of SpecPkt 810 ; mov ax,4B01h ;Get Bootable CD-ROM Status 811 ; int 13h 812 ; jnc FindPass ;If booted CD found 813 ; 814 ; Carry is not cleared in buggy Dell BIOSes, 815 ; so I'm checking packet size byte 816 ; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed 817 ; Dell Dimension XPsT returns packet size 0x14 when OK 818 819 ; cmp [SpecPkt], 0 820 ; jne FoundBoot 821 822 ; cmp [SpecPkt], 13h ; anything between 13h and 20h should be OK 823 ; jb FindFail 824 ; cmp [SpecPkt], 20h 825 ; ja FindFail 826 ; jmp short FoundBoot 827 ; 828 ; FindFail: 829 ; dec dl ;Next drive 830 ; cmp dl, 80h 831 ; jae FindBoot ;Check from ffh..80h 832 ; *** end of 1.4 changes *** 833 834 00000C2C BE[1D0E] mov si,NoBootCD ;No booted CD found, 835 00000C2F E895F7 call print_string 836 00000C32 E93401 jmp NoEndAddr ;Do not install driver 837 838 FoundBoot: 839 ; mov dl, [SpecPkt+2] ; 1.4 change 840 ; *** next line at c57 in 1.4, at c3d in 1.3 *** 841 00000C35 8816[4400] mov [DriveNumber],dl ;Booted CD-ROM found, 842 ; so save Drive # 843 844 00000C39 E8B401 call keyflag 845 00000C3C 2408 and al, 8 ; alt key ? 846 00000C3E 741F jz extread 847 848 00000C40 BE[390E] mov si, CDStat 849 00000C43 E881F7 call print_string 850 00000C46 BE[7A00] mov si, SpecPkt ;Point to returned CD SpecPkt 851 00000C49 B91300 mov cx, 19 ; containing 19 bytes 852 00000C4C B020 StatDump: mov al, ' ' ;Print a space 853 00000C4E E887F7 call print_char 854 00000C51 8A04 mov al, byte [si] ;Hexdump a SpecPkt byte 855 00000C53 E836F7 call print_hex8 856 00000C56 46 inc si ;Point to next byte 857 00000C57 E2F3 loop StatDump 858 859 00000C59 BE[2F0F] mov si, LineEnd ;Print a CR/LF 860 00000C5C E868F7 call print_string 861 862 extread: 863 ;See how many CD Sector bytes are returned by an Extended Read 864 00000C5F C606[7A00]10 mov byte [SpecPkt],16 ;SpecPkt Size 865 00000C64 C606[7B00]00 mov byte [SpecPkt+1],0 ;Reserved 866 00000C69 C706[7C00]0100 mov word [SpecPkt+2],1 ;Transfer one sector 867 00000C6F 8C0E[8000] mov word [SpecPkt+6],cs ;Into our Buffer 868 00000C73 C706[7E00][F003] mov word [SpecPkt+4],Buffer 869 00000C79 C706[8200]1000 mov word [SpecPkt+8],16 ;From CD Sector 16 870 00000C7F C706[8400]0000 mov word [SpecPkt+10],0 871 00000C85 C706[8600]0000 mov word [SpecPkt+12],0 872 00000C8B C706[8800]0000 mov word [SpecPkt+14],0 873 874 00000C91 BE[7A00] mov si, SpecPkt ;Set ds:si --> SpecPkt 875 00000C94 8A16[4400] mov dl, [DriveNumber] 876 00000C98 B442 mov ah, 42h ;Extended Read 877 00000C9A CD13 int 13h 878 00000C9C 7304 jnc SecSize ;If success 879 880 00000C9E B442 mov ah, 42h ;Always make 2 read attempts 881 00000CA0 CD13 int 13h 882 ;How many bytes did we get? 883 00000CA2 FD SecSize: std ;Count down 884 00000CA3 8CC8 mov ax,cs ;Point to end of Buffer 885 00000CA5 8EC0 mov es,ax 886 00000CA7 BF[EF0B] mov di,Buffer+2047 ;Find end of read data 887 00000CAA BE[F00B] mov si,Buffer+2048 888 00000CAD B90108 mov cx,2049 889 00000CB0 F3A6 repe cmpsb ;cx = number of bytes read 890 891 00000CB2 FC cld ;Restore count direction to up 892 00000CB3 BE[7D0E] mov si,CDBytes ;Display number of bytes read 893 00000CB6 E80EF7 call print_string 894 895 00000CB9 A0[4400] mov al, [DriveNumber] 896 00000CBC E8CDF6 call print_hex8 897 898 00000CBF BE[860E] mov si,CDBytesA ;Remainder A of message 899 00000CC2 E802F7 call print_string 900 901 00000CC5 88E8 mov al,ch ;Hex-dump cx 902 00000CC7 240F and al,0Fh ;Second nibble 903 00000CC9 E8C0F6 call print_hex8 ; (don't need the First) 904 00000CCC 88C8 mov al,cl 905 00000CCE E8BBF6 call print_hex8 ; (don't need the First) 906 907 00000CD1 BE[900E] mov si,CDBytesB ;Remainder B of message 908 00000CD4 E8F0F6 call print_string 909 910 00000CD7 81F90008 cmp cx,2048 ;Did we read 2048 bytes? 911 00000CDB 7416 je ParseParm ;If yes <-- O.K. 912 913 00000CDD C606[4500]01 mov byte [ReadBytes],1 914 00000CE2 81F90004 cmp cx,1024 ;Did we read 1024 bytes? 915 00000CE6 740B je ParseParm ;If yes <-- O.K. 916 917 00000CE8 C606[4500]02 mov byte [ReadBytes],2 918 00000CED 81F90002 cmp cx,512 ;Did we read 512 bytes? 919 00000CF1 7576 jne NoEndAddr ;If not, do not load driver 920 921 00000CF3 2E8B1E[3800] ParseParm: mov bx,word [cs:ReqHdrLoc] ;Parse command line 922 00000CF8 2E8E06[3A00] mov es,word [cs:ReqHdrLoc+2] ; parameters 923 00000CFD 268B7712 mov si,[es:bx+18] ;Get BPB array ptr into DS:SI 924 00000D01 268E5F14 mov ds,[es:bx+20] 925 00000D05 46 FindParm: inc si 926 00000D06 803C0D FindParm1: cmp byte [si],0Dh ;CR? (End of parameters) 927 00000D09 7452 je EndOfParms 928 929 00000D0B 803C0A cmp byte [si],0Ah ;LF? 930 00000D0E 744D je EndOfParms 931 932 00000D10 803C2F cmp byte [si],'/' ;A parameter? 933 00000D13 75F0 jne FindParm 934 935 00000D15 46 inc si 936 00000D16 803C44 cmp byte [si],'D' ;Device Name parameter? 937 00000D19 75EB jne FindParm1 938 939 00000D1B 46 inc si 940 00000D1C 803C3A cmp byte [si],':' 941 00000D1F 75E5 jne FindParm1 942 943 ;bbb 944 00000D21 56 push si 945 00000D22 BE[A60E] mov si, DevName ;Device Name is at ds:si 946 00000D25 1E push ds ;Keep ptr to Device Name 947 00000D26 8CC8 mov ax, cs 948 00000D28 8ED8 mov ds, ax 949 00000D2A E89AF6 call print_string 950 00000D2D 1F pop ds ;Retrieve Device Name ptr 951 00000D2E 5E pop si 952 00000D2F B90800 mov cx, 8 ;Get next 8 chars 953 00000D32 46 inc si ; = Device Name 954 00000D33 8CC8 mov ax, cs 955 00000D35 8EC0 mov es, ax 956 00000D37 BF[0A00] mov di, DeviceName 957 00000D3A 803C20 NextChar: cmp byte [si],' ' 958 00000D3D 7707 ja AboveSpace 959 960 00000D3F 8CC8 mov ax,cs ;Pad end of Device Name with 961 00000D41 8ED8 mov ds,ax ; spaces if necessary 962 00000D43 BE[2301] mov si,DblSpace ;A space 963 00000D46 8A04 AboveSpace: mov al, [si] 964 00000D48 E88DF6 call print_char 965 00000D4B A4 movsb ;ds:[si] --> es:[di] 966 00000D4C E2EC loop NextChar 967 968 00000D4E BE[2F0F] mov si,LineEnd 969 00000D51 8CC8 mov ax,cs 970 00000D53 8ED8 mov ds,ax 971 00000D55 E86FF6 call print_string 972 973 00000D58 B8[EF0B] mov ax,Init-2 ;Last byte of driver to keep 974 00000D5B EB0F jmp EndAddr ;Install driver 975 976 EndOfParms: 977 00000D5D 8CC8 mov ax, cs ; Restore segment registers (fix) 978 00000D5F 8ED8 mov ds, ax 979 00000D61 8EC0 mov es, ax 980 981 00000D63 BE[B60E] mov si,NoDevName ;No Device Name Found 982 00000D66 E85EF6 call print_string 983 984 00000D69 B80000 NoEndAddr: mov ax,0 ;Do not install driver 985 986 00000D6C 8E06[3A00] EndAddr: mov es,[ReqHdrLoc+2] ;Write End Address 987 00000D70 8B1E[3800] mov bx,[ReqHdrLoc] 988 00000D74 2689470E mov [es:bx+14],ax 989 00000D78 268C4F10 mov [es:bx+16],cs 990 00000D7C 89C3 mov bx,ax ;Hold onto install status 991 992 00000D7E BE[F80E] mov si, DrvInst ;Display driver install status 993 00000D81 E843F6 call print_string 994 00000D84 BE[070F] mov si, DrvInst1 ;Assume driver installed 995 00000D87 83FB00 cmp bx,0 ;Was driver installed? 996 00000D8A 7503 jne DrvStatus ;If yes 997 00000D8C BE[020F] mov si, NoDrvInst ;Driver not installed 998 00000D8F E835F6 DrvStatus: call print_string 999 1000 00000D92 B80000 mov ax,0 ;Set Return Status = success 1001 00000D95 83FB00 cmp bx,0 ;Was INIT successful? 1002 00000D98 7503 jne InitStat ;If yes 1003 00000D9A B80C80 mov ax,800Ch ;Status = General Failure 1004 InitStat: 1005 00000D9D 50 push ax ;Save Return Status 1006 1007 00000D9E E84F00 call keyflag 1008 00000DA1 2408 and al, 8 ; alt key ? 1009 00000DA3 740D jz InitExit 1010 1011 WaitHere: 1012 00000DA5 BE[130F] mov si, WaitMsg ;Display Halted message 1013 00000DA8 E81CF6 call print_string 1014 1015 AltWait: 1016 00000DAB E84200 call keyflag 1017 00000DAE 2408 and al, 8 ; Alt key? 1018 00000DB0 75F9 jnz AltWait ; Pressed? yes -> wait 1019 1020 InitExit: 1021 00000DB2 58 pop ax ;Retrieve Return Status 1022 TRACER 'i' 1023 00000DB3 C3 retn ;That's it for Init! 1024 1025 ; *** start 1.4 changes at ded *** 1026 00000DB4 BE[7A00] SpecGo: mov si,SpecPkt 1027 00000DB7 CD13 int 13h 1028 00000DB9 C3 retn 1029 1030 00000DBA 50 ScanDrives: push ax ; at df3 in 1.4 1031 00000DBB 56 push si 1032 00000DBC B27F mov dl, 7fh ;Start at Drive 0x80 1033 00000DBE FEC2 NextDrv: inc dl 1034 00000DC0 F8 clc 1035 00000DC1 B8014B mov ax,4B01h ;Get Bootable CD-ROM Status 1036 00000DC4 C606[7A00]00 mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt 1037 00000DC9 E8E8FF call SpecGo 1038 ; Carry is not cleared in buggy Dell BIOSes, 1039 ; so I'm checking packet size byte 1040 ; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed 1041 ; Dell Dimension XPsT returns packet size 0x14 when OK 1042 1043 00000DCC 803E[7A00]13 cmp BYTE [SpecPkt], 13h ; anything between 13h and 20h should be OK 1044 00000DD1 7209 jb FindFail 1045 00000DD3 803E[7A00]20 cmp BYTE [SpecPkt], 20h 1046 00000DD8 7702 ja FindFail ; in 1.4 at e16 1047 00000DDA EB0C jmp short SendFound ; in 1.4 at e26 1048 1049 00000DDC 80FAFF FindFail: cmp dl, 0ffh 1050 00000DDF 7402 je SendFail ; Check from 80h..ffh 1051 00000DE1 EBDB jmp short NextDrv ;Next drive 1052 00000DE3 30D2 SendFail: xor dl,dl 1053 00000DE5 F9 stc 1054 00000DE6 EB05 jmp short ThingDone 1055 00000DE8 8A16[7C00] SendFound: mov dl, [SpecPkt+2] 1056 00000DEC F8 clc 1057 00000DED 5E ThingDone: pop si 1058 00000DEE 58 pop ax 1059 00000DEF C3 retn 1060 ; *** end 1.4 changes *** 1061 1062 ;============================================================================= 1063 1064 ;------------------------------------------------------------ 1065 ; keyboard flags - return keyboard flags in AL 1066 ; bit 3 = ALT key 1067 keyflag: ; at dbc in 1.3, at e2e in 1.4 1068 00000DF0 53 push bx 1069 00000DF1 B402 mov ah, 2 1070 00000DF3 CD16 int 16h 1071 00000DF5 5B pop bx 1072 00000DF6 C3 retn 1073 1074 ;============================================================================= 1075 1076 00000DF7 20204469736B656D78- DrvNumMsg db ' Diskemxx.bin returned drive number=', 0 1076 00000E00 782E62696E20726574- 1076 00000E09 75726E656420647269- 1076 00000E12 7665206E756D626572- 1076 00000E1B 3D00 1077 00000E1D 20204E6F20626F6F74- NoBootCD db ' No booted CD-ROM found.',CR,0 1077 00000E26 65642043442D524F4D- 1077 00000E2F 20666F756E642E0D0A- 1077 00000E38 00 1078 1079 00000E39 2020494E5420313368- CDStat db ' INT 13h / AX=4B01h Specification Packet for ' 1079 00000E42 202F2041583D344230- 1079 00000E4B 316820537065636966- 1079 00000E54 69636174696F6E2050- 1079 00000E5D 61636B657420666F72- 1079 00000E66 20 1080 00000E67 426F6F746564204344- db 'Booted CD-ROM:',CR,' ', 0 1080 00000E70 2D524F4D3A0D0A2020- 1080 00000E79 20202000 1081 1082 00000E7D 202044726976652000 CDBytes db ' Drive ', 0 1083 00000E86 2072657475726E7320- CDBytesA db ' returns ', 0 1083 00000E8F 00 1084 00000E90 682062797465732070- CDBytesB db 'h bytes per Sector.',CR,0 1084 00000E99 657220536563746F72- 1084 00000EA2 2E0D0A00 1085 1086 00000EA6 202044657669636520- DevName db ' Device Name: ', 0 1086 00000EAF 4E616D653A2000 1087 00000EB6 20204E6F2044657669- NoDevName db ' No Device Name found. ' 1087 00000EBF 6365204E616D652066- 1087 00000EC8 6F756E642E20 1088 00000ECE 55736167653A206465- db 'Usage: device=eltorito.sys /D:',CR,0 1088 00000ED7 766963653D656C746F- 1088 00000EE0 7269746F2E73797320- 1088 00000EE9 2F443A3C4465764E61- 1088 00000EF2 6D653E0D0A00 1089 1090 00000EF8 202044726976657220- DrvInst db ' Driver ', 0 1090 00000F01 00 1091 00000F02 076E6F7420 NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep 1092 00000F07 696E7374616C6C6564- DrvInst1 db 'installed',CR,0 1092 00000F10 0D0A00 1093 1094 00000F13 2020416C7420707265- WaitMsg db ' Alt pressed, waiting...', CR, 0 1094 00000F1C 737365642C20776169- 1094 00000F25 74696E672E2E2E0D0A- 1094 00000F2E 00 1095 ;ContMsg db ' Continuing...' 1096 00000F2F 0D0A00 LineEnd db CR,0 1097 1098 1099 ;=============================================================================