;----------------------------------------------------------------------------- ; ElTorito.asm ; ; El Torito Bootable CD-ROM driver which does not reset the CD-ROM drive upon ; loading, but instead accesses the drive through BIOS system calls ; ; MIT License ; ; (c) 2000 by Gary Tong ; (c) 2001-2009 by Bart Lagerweij ; ; Permission is hereby granted, free of charge, to any person obtaining a copy ; of this software and associated documentation files (the "Software"), to deal ; in the Software without restriction, including without limitation the rights ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ; copies of the Software, and to permit persons to whom the Software is ; furnished to do so, subject to the following conditions: ; ; The above copyright notice and this permission notice shall be included in ; all copies or substantial portions of the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ; THE SOFTWARE. ; ;----------------------------------------------------------------------------- ; To assemble and link, use these commands with NASM 2.x: ; nasm -Ox -f bin -o eltorito.sys eltorito.asm ; To enable Trace markers uncomment the line below ; DEBUG_TRACERS=1 ; To enable debug info uncomment the line below ; DEBUG=1 %ifdef DEBUG_TRACERS %macro TRACER 1 call debug_tracer db %1 %endmacro %else %macro TRACER 1 %endmacro %endif ; DEBUG_TRACERS %define Ver '1.5' %define CR 0DH, 0Ah RPolyH equ 0EDB8h RPolyL equ 08320h section .text align=16 org 0 ;============================================================================= Cdrom: NextDriver dd -1 ;-+ Attributes dw 0C800h ; | Pointers dw Strategy ; | dw Commands ; | MSCDEX requires this DeviceName db 'ELTORITO' ; | data in these locations dw 0 ; | DriveLetter db 0 ; | NumUnitsSupp db 1 ;-+ DriverName db 'El-Torito CD-ROM Device Driver',0 align 4, db 0 ReqHdrLoc dd 0 XferAddr dd 0 Checksum dd -1 DriveNumber db 0 ReadBytes db 0 ;0 --> 2048 bytes/sector ;1 --> 1024 bytes/sector ;2 --> 512 bytes/sector Routines dw Init ;Init ;0 dw Unsupported ;MediaCheck ;1 dw Unsupported ;BuildBPB ;2 dw IoctlInput ;IoctlInput ;3 dw Unsupported ;Input ;4 dw Unsupported ;NonDesInput ;5 dw Unsupported ;InputStatus ;6 dw Unsupported ;InputFlush ;7 dw Unsupported ;Output ;8 dw Unsupported ;OutputVerify ;9 dw Unsupported ;OutputStatus ;10 dw Unsupported ;OutputFlush ;11 dw IoctlOutput ;IoctlOutput ;12 dw DoNothing ;DeviceOpen ;13 dw DoNothing ;DeviceClose ;14 dw ReadL ;ReadL ;128 IoctlICtrl dw Raddr ;Raddr ;0 dw Unsupported ;LocHead ;1 dw Unsupported ;(Reserved) ;2 dw Unsupported ;ErrStat ;3 dw Unsupported ;AudInfo ;4 dw DrvBytes ;DrvBytes ;5 dw DevStat ;DevStat ;6 dw SectSize ;SectSize ;7 dw VolSize ;VolSize ;8 dw MedChng ;MedChng ;9 SpecPkt times 19 db 0 ; offset 77h in 1.4 times 13 db 0 ; unknown extra 00s in 1.4 Greeting db 'El-Torito Bootable CD-ROM Driver for Dos v',Ver,', http://www.nu2.nu/eltorito/',CR db ' (c) 2000 by Gary Tong',CR db ' (c) 2001-2002 by Bart Lagerweij',CR,0 DblSpace db ' ',0 ;============================================================================= Strategy: mov word [cs:ReqHdrLoc],bx mov word [cs:ReqHdrLoc+2],es retf ;============================================================================= Commands: push ax push bx push cx push dx push si push di push bp ; pushad push ds push es TRACER 'C' cld ;Clear direction sti ;Enable interrupts mov ax, cs ;ds=cs mov ds, ax les bx,[ReqHdrLoc] ;seg:offset ptr into es:bx xor ax,ax mov al,[es:bx+2] ;Get Command code %ifdef DEBUG call print_hex8 %endif cmp al,15 jb Mult2 ;If 0-14 cmp al,128 jb UnknownCmd ;If 15-127 cmp al,129 jb ShiftDown ;If 128 UnknownCmd: mov al,121 ;8 = Unsupported (Reserved) ShiftDown: sub al,113 ;128 --> 15, 121 --> 8 Mult2: shl al,1 ;Convert into offset (*2) mov di,Routines add di,ax call word [di] ;Execute desired command or ax,100h ;Set Return Status's Done bit lds bx,[ReqHdrLoc] ;seg:offset ptr into ds:bx mov [bx+3],ax ;Save Status %ifdef DEBUG cmp byte [cs:buffer+2048], 96h je buffer_ok mov al, '!' call print_char jmp $ buffer_ok: %endif TRACER 'c' pop es pop ds ; popad pop bp pop di pop si pop dx pop cx pop bx pop ax retf ;============================================================================= Unsupported: ;Unsupported Command mov ax,8003h ;Set Status Error bit, TRACER 'U' TRACER 'C' retn ; Error 3 = Unknown Command ;============================================================================= IoctlInput: ;IOCTL Input Routine mov di,[es:bx+14] ;es:bx --> Request Header mov es,[es:bx+16] ;Get Xfer Address into es:di xor ax,ax ;Get Control Block Code mov al,[es:di] %ifdef DEBUG TRACER 'I' TRACER 'O' call print_hex8 %endif cmp al,10 jb UnkIoctlI ;If 0-9 mov al,2 ;Map to Unsupported UnkIoctlI: shl al,1 ;Convert into offset (*2) mov si,IoctlICtrl add si,ax call word [si] ;Execute desired command retn ;============================================================================= Raddr: ;Return Device Header Address TRACER 'A' mov word [es:di+1],0 mov [es:di+3],cs xor ax, ax ;Set Return Status = success TRACER 'a' retn ;============================================================================= DrvBytes: ;Read Drive Bytes TRACER 'B' push di ;Save original Xfer Addr add di,2 ;Point to 1st dest byte mov si,Greeting ;Point to Greeting DrvB: movsb ;Copy over a byte cmp byte [si],13 ;Is next char a CR? jne DrvB ;Loop if not sub di,2 ;Get #bytes copied into ax mov ax,di pop di ;Retrieve original Xfer Addr sub ax,di mov byte [es:di+1],al ;and save it mov ax,0 ;Set Return Status = success TRACER 'b' retn ;============================================================================= DevStat: ;Return Device Status TRACER 'D' mov word [es:di+1],202h ;Door closed mov word [es:di+3],0 ;Door unlocked ;Supports only cooked reading ;Read only ;Data read only ;No interleaving ;No prefetching ;No audio channel manipulation ;Supports both HSG and Redbook ; addressing modes xor ax, ax ;Set Return Status = success TRACER 'd' retn ;============================================================================= SectSize: ;Return Sector Size TRACER 'S' mov word [es:di+2],2048 mov ax,0 ;Set Return Status = success TRACER 's' retn ;============================================================================= VolSize: ;Return Volume Size TRACER 'V' call PriVolDesc ;Get and Check Primary Volume ; Descriptor mov ax,800Fh ;Assume Invalid Disk Change jc VolExit ;If Read Failure mov ax,word [Buffer+80] ;Read Successful mov word [es:di+1],ax ;Copy over Volume Size mov ax,word [Buffer+82] mov word [es:di+3],ax mov ax,0 ;Set Return Status = success VolExit: TRACER 'v' retn ;============================================================================= MedChng: ;Return Media Changed Status TRACER 'M' call PriVolDesc ;Get and Check Primary Volume ; Descriptor mov byte [es:di+1],-1 ;Assume Media Changed mov ax,800Fh ; and Invalid Disk Change jc MedExit ;If Media Changed or Bad mov byte [es:di+1],1 ;Media has not changed mov ax,0 ;Set Return Status = success MedExit: TRACER 'm' retn ;============================================================================= PriVolDesc: ;Get and Check Primary Volume ; Descriptor TRACER 'P' mov ax,cs ;Set ds:si --> SpecPkt mov ds,ax mov cx, 5 PriVolAgain: mov byte [SpecPkt],16 ;SpecPkt Size mov byte [SpecPkt+1],0 ;Reserved mov word [SpecPkt+2],1 ;Transfer one 2048-byte sector push cx mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 shl word [SpecPkt+2],cl ; bytes at a time pop cx mov word [SpecPkt+6],cs ;Into our Buffer mov word [SpecPkt+4], Buffer mov word [SpecPkt+8],16 ;From CD Sector 16 mov word [SpecPkt+10],0 mov word [SpecPkt+12],0 mov word [SpecPkt+14],0 mov si, SpecPkt mov dl, [DriveNumber] mov ah, 42h ;Extended Read int 13h jnc PriVolPass ;If success ; TRACER '1' ; read error loop PriVolAgain TRACER '2' ; read retries exhausted ; flow into below jmp PriReadErr PriVolPass: mov si,Buffer ;Point input to Buffer mov ax,-1 ;Init Checksum registers mov bx,ax ; bx,ax = 0FFFFFFFFh jc PriNew ;If Read Failure push di ;Read Successful, ; so Calculate Checksum mov di,1024 ;Init Word counter PriWord: mov dx,[cs:si] ;Grab next word from buffer mov cx,16 ;Init bit counter PriBit: shr dx,1 ;Shift everything right 1 bit rcr bx,1 rcr ax,1 jnc NoMult ;If a zero shifted out xor bx,RPolyH ;A one shifted out, so XOR xor ax,RPolyL ; Checksum with RPoly NoMult: loop PriBit add si,2 ;Inc Word Pointer dec di ja PriWord TRACER '3' pop di ;Checksum calculation complete cmp bx,[Checksum+2] ;Has Checksum changed? jne PriNew ;If Checksum Changed cmp ax,[Checksum] jne PriNew ;If Checksum Changed clc ;Checksum not changed, CF=0 mov ax,0 ;Status = success jmp PriOld PriReadErr: mov WORD [Checksum+2],bx ;Save New Checksum mov [Checksum],ax ; or 0FFFFFFFFh if bad read stc ;Checksum change, CF=1 mov ax, 800bh ;Status = read fault jmp PriOld PriNew: mov WORD [Checksum+2],bx ;Save New Checksum mov [Checksum],ax ; or 0FFFFFFFFh if bad read stc ;Checksum Changed, CF=1 mov ax,800Fh ;Status = Invalid Media Change PriOld: TRACER 'p' retn ;============================================================================= IoctlOutput: ;IOCTL Output Routine TRACER 'O' mov di,[es:bx+14] ;es:bx --> Request Header mov es,[es:bx+16] ;Get Xfer Address into es:di xor ax,ax ;Get Control Block Code mov al,[es:di] cmp al,2 jne UnkIoctlO ;If not 2 (ResetDrv) call DoNothing ;Reset Drive jmp IoctlODone UnkIoctlO: call Unsupported ;Unsupported command IoctlODone: TRACER 'o' retn ;============================================================================= DoNothing: ;Do Nothing Command mov ax,0 ;Set Return Status = success retn ;============================================================================= ReadL: ;Read Long Command TRACER 'R' mov ax,cs ;Set ds=cs mov ds,ax ;es:bx --> Request Header cmp byte [es:bx+24],0 ;Check Data Read Mode jne ReadLErr ;If Cooked Mode cmp byte [es:bx+13],2 ;Check Addressing Mode jb ReadLOK ;If HSG or Redbook Mode ReadLErr: TRACER '8' mov ax,8003h ;Set Return Status = Unknown jmp ReadLExit ; Command Error and exit ReadLOK: mov ax,[es:bx+20] ;Get Starting Sector Number, mov dx,[es:bx+22] ; Assume HSG Addressing Mode cmp byte [es:bx+13],0 ;Check Addressing Mode again je ReadLHSG ;If HSG Addressing Mode TRACER '7' ;Using Redbook Addressing Mode. Convert to HSG format mov al,dl ;Get Minutes mov dl,60 mul dl ;ax = Minutes * 60 add al,byte [es:bx+21] ;Add in Seconds adc ah,0 mov dx,75 ;dx:ax = mul dx ; ((Min * 60) + Sec) * 75 add al,byte [es:bx+20] ;Add in Frames adc ah,0 adc dx,0 sub ax,150 ;Subtract 2-Second offset sbb dx,0 ;dx:ax = HSG Starting Sector ReadLHSG: mov word [SpecPkt+8], ax ;Store Starting mov word [SpecPkt+10], dx ; Sector Number mov word [SpecPkt+12], 0 ; (HSG Format) mov word [SpecPkt+14], 0 mov ax,[es:bx+14] ;Get Transfer Address mov word [SpecPkt+4],ax mov ax,[es:bx+16] mov word [SpecPkt+6],ax mov byte [SpecPkt],16 ;Size of Disk Address Packet mov byte [SpecPkt+1],0 ;Reserved mov cx, 5 ReadLAgain: mov ax,[es:bx+18] ;Get number of sectors to read mov word [SpecPkt+2],ax cmp ax, 3FFFh ;Too large? ja ReadLBad ;If yes push cx mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512 shl word [SpecPkt+2],cl ; bytes at a time pop cx %ifdef DEBUG push ax push cx push si mov cx, 16 mov si,SpecPkt ReadDump: mov al, ' ' call print_char mov al, byte [si] ;Hexdump a SpecPkt byte call print_hex8 inc si ;Point to next byte loop ReadDump pop si pop cx pop ax %endif mov si,SpecPkt mov dl,[DriveNumber] mov ah,42h ;Extended Read int 13h jnc ReadLGd ;If success ;hang: ; jmp hang ; TRACER '1' loop ReadLAgain TRACER '2' jmp short ReadLBad ReadLGd: TRACER '3' xor ax, ax ;Status 0 = success jmp short ReadLExit ReadLBad: TRACER '9' mov ax, 800Bh ;Set Read Fault Error ; flow into ReadLExit ReadLExit: TRACER 'r' retn %ifdef DEBUG_TRACERS debug_tracer: pushad pushfd mov al, '[' mov ah,0Eh ;BIOS video teletype output xor bh, bh int 10h ;Print it mov bp,sp mov bx,[bp+9*4] ; Get return address mov al,[cs:bx] ; Get data byte inc word [bp+9*4] ; Return to after data byte mov ah,0Eh ;BIOS video teletype output xor bh, bh int 10h ;Print it mov al, ']' mov ah,0Eh ;BIOS video teletype output xor bh, bh int 10h ;Print it popfd popad retn %endif ;----------------------------------------------------------------------------- ; PRINT_HEX4 ;----------------------------------------------------------------------------- ; print a 4 bits integer in hex ; ; Input: ; AL - 4 bits integer to print (low) ; ; Output: None ; ; Registers destroyed: None ; print_hex4: push ax and al, 0fh ; we only need the first nibble cmp al, 10 jae hex_A_F add al, '0' jmp hex_0_9 hex_A_F: add al, 'A'-10 hex_0_9: call print_char pop ax retn ;----------------------------------------------------------------------------- ; print_hex8 ;----------------------------------------------------------------------------- ; print a 8 bits integer in hex ; ; Input: ; AL - 8 bits integer to print ; ; Output: None ; ; Registers destroyed: None ; print_hex8: push ax push bx mov ah, al shr al, 4 call print_hex4 mov al, ah and al, 0fh call print_hex4 pop bx pop ax retn ;============================================================================= ; print_hex16 - print a 16 bits integer in hex ; ; Input: ; AX - 16 bits integer to print ; ; Output: None ; ; Registers destroyed: None ;============================================================================= print_hex16: push ax push bx push cx mov cx, 4 print_hex16_loop: rol ax, 4 call print_hex4 loop print_hex16_loop pop cx pop bx pop ax retn ;============================================================================= ; print_hex32 - print a 32 bits integer in hex ; ; Input: ; EAX - 32 bits integer to print ; ; Output: None ; ; Registers destroyed: None ;============================================================================= print_hex32: push eax push bx push cx mov cx, 8 print_hex32_loop: rol eax, 4 call print_hex4 loop print_hex32_loop pop cx pop bx pop eax retn ;============================================================================= ; print_string - print string at current cursor location ; ; Input: ; DS:SI - ASCIIZ string to print ; ; Output: None ; ; Registers destroyed: None ;============================================================================= print_string: push ax push si print_string_again: mov al, [si] or al, al jz print_string_exit call print_char inc si jmp print_string_again print_string_exit: pop si pop ax retn ;----------------------------------------------------------------------------- ; PRINT_CHAR ;----------------------------------------------------------------------------- ; Print's a character at current cursor position ; ; Input: ; AL - Character to print ; ; Output: None ; ; Registers destroyed: None ; print_char: push ax push bx mov ah,0Eh ;BIOS video teletype output xor bh, bh int 10h ;Print it print_char_exit: pop bx pop ax retn ;============================================================================= ;This space is used as a 2048-byte read buffer plus one test byte. ;The 96h data is used for testing the number of bytes returned by an Extended ; CD-ROM sector read align 16, db 0 Buffer times 2049 db 96h ;============================================================================= Init: ;Initialization Routine TRACER 'I' mov ax,cs ;ds=cs mov ds,ax %ifdef DEBUG ; print CS value (load segment) call print_hex16 %endif mov si, Greeting ;Display Greeting call print_string mov ax,Unsupported ;Init is executed only once mov [Routines],ax mov ax, 5400h int 13h ; Get diskemu status jc FindBoot ; If CF=1 no diskemu loaded mov [DriveNumber], cl ; Store drive number call keyflag and al, 8 ; alt key ? jz extread mov si, DrvNumMsg ; Display "drive number=" call print_string mov al, [DriveNumber] call print_hex8 mov si, LineEnd ; CR/LF call print_string jmp extread ; Diskemu is not loaded ; so loop to find drive number ; *** start of 1.4 changes *** ; ??? mov dl, 0ffh ;Start at Drive 0xff ; *** FindBoot at c47 in 1.4, at c0c in 1.3 *** FindBoot: call ScanDrives ; call new helper in 1.4 jnc FoundBoot ; ded*df3 ; mov si,offset SpecPkt ;Locate booted CD-ROM drive ; mov [SpecPkt],0 ;Clear 1st byte of SpecPkt ; mov ax,4B01h ;Get Bootable CD-ROM Status ; int 13h ; jnc FindPass ;If booted CD found ; ; Carry is not cleared in buggy Dell BIOSes, ; so I'm checking packet size byte ; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed ; Dell Dimension XPsT returns packet size 0x14 when OK ; cmp [SpecPkt], 0 ; jne FoundBoot ; cmp [SpecPkt], 13h ; anything between 13h and 20h should be OK ; jb FindFail ; cmp [SpecPkt], 20h ; ja FindFail ; jmp short FoundBoot ; ; FindFail: ; dec dl ;Next drive ; cmp dl, 80h ; jae FindBoot ;Check from ffh..80h ; *** end of 1.4 changes *** mov si,NoBootCD ;No booted CD found, call print_string jmp NoEndAddr ;Do not install driver FoundBoot: ; mov dl, [SpecPkt+2] ; 1.4 change ; *** next line at c57 in 1.4, at c3d in 1.3 *** mov [DriveNumber],dl ;Booted CD-ROM found, ; so save Drive # call keyflag and al, 8 ; alt key ? jz extread mov si, CDStat call print_string mov si, SpecPkt ;Point to returned CD SpecPkt mov cx, 19 ; containing 19 bytes StatDump: mov al, ' ' ;Print a space call print_char mov al, byte [si] ;Hexdump a SpecPkt byte call print_hex8 inc si ;Point to next byte loop StatDump mov si, LineEnd ;Print a CR/LF call print_string extread: ;See how many CD Sector bytes are returned by an Extended Read mov byte [SpecPkt],16 ;SpecPkt Size mov byte [SpecPkt+1],0 ;Reserved mov word [SpecPkt+2],1 ;Transfer one sector mov word [SpecPkt+6],cs ;Into our Buffer mov word [SpecPkt+4],Buffer mov word [SpecPkt+8],16 ;From CD Sector 16 mov word [SpecPkt+10],0 mov word [SpecPkt+12],0 mov word [SpecPkt+14],0 mov si, SpecPkt ;Set ds:si --> SpecPkt mov dl, [DriveNumber] mov ah, 42h ;Extended Read int 13h jnc SecSize ;If success mov ah, 42h ;Always make 2 read attempts int 13h ;How many bytes did we get? SecSize: std ;Count down mov ax,cs ;Point to end of Buffer mov es,ax mov di,Buffer+2047 ;Find end of read data mov si,Buffer+2048 mov cx,2049 repe cmpsb ;cx = number of bytes read cld ;Restore count direction to up mov si,CDBytes ;Display number of bytes read call print_string mov al, [DriveNumber] call print_hex8 mov si,CDBytesA ;Remainder A of message call print_string mov al,ch ;Hex-dump cx and al,0Fh ;Second nibble call print_hex8 ; (don't need the First) mov al,cl call print_hex8 ; (don't need the First) mov si,CDBytesB ;Remainder B of message call print_string cmp cx,2048 ;Did we read 2048 bytes? je ParseParm ;If yes <-- O.K. mov byte [ReadBytes],1 cmp cx,1024 ;Did we read 1024 bytes? je ParseParm ;If yes <-- O.K. mov byte [ReadBytes],2 cmp cx,512 ;Did we read 512 bytes? jne NoEndAddr ;If not, do not load driver ParseParm: mov bx,word [cs:ReqHdrLoc] ;Parse command line mov es,word [cs:ReqHdrLoc+2] ; parameters mov si,[es:bx+18] ;Get BPB array ptr into DS:SI mov ds,[es:bx+20] FindParm: inc si FindParm1: cmp byte [si],0Dh ;CR? (End of parameters) je EndOfParms cmp byte [si],0Ah ;LF? je EndOfParms cmp byte [si],'/' ;A parameter? jne FindParm inc si cmp byte [si],'D' ;Device Name parameter? jne FindParm1 inc si cmp byte [si],':' jne FindParm1 ;bbb push si mov si, DevName ;Device Name is at ds:si push ds ;Keep ptr to Device Name mov ax, cs mov ds, ax call print_string pop ds ;Retrieve Device Name ptr pop si mov cx, 8 ;Get next 8 chars inc si ; = Device Name mov ax, cs mov es, ax mov di, DeviceName NextChar: cmp byte [si],' ' ja AboveSpace mov ax,cs ;Pad end of Device Name with mov ds,ax ; spaces if necessary mov si,DblSpace ;A space AboveSpace: mov al, [si] call print_char movsb ;ds:[si] --> es:[di] loop NextChar mov si,LineEnd mov ax,cs mov ds,ax call print_string mov ax,Init-2 ;Last byte of driver to keep jmp EndAddr ;Install driver EndOfParms: mov ax, cs ; Restore segment registers (fix) mov ds, ax mov es, ax mov si,NoDevName ;No Device Name Found call print_string NoEndAddr: mov ax,0 ;Do not install driver EndAddr: mov es,[ReqHdrLoc+2] ;Write End Address mov bx,[ReqHdrLoc] mov [es:bx+14],ax mov [es:bx+16],cs mov bx,ax ;Hold onto install status mov si, DrvInst ;Display driver install status call print_string mov si, DrvInst1 ;Assume driver installed cmp bx,0 ;Was driver installed? jne DrvStatus ;If yes mov si, NoDrvInst ;Driver not installed DrvStatus: call print_string mov ax,0 ;Set Return Status = success cmp bx,0 ;Was INIT successful? jne InitStat ;If yes mov ax,800Ch ;Status = General Failure InitStat: push ax ;Save Return Status call keyflag and al, 8 ; alt key ? jz InitExit WaitHere: mov si, WaitMsg ;Display Halted message call print_string AltWait: call keyflag and al, 8 ; Alt key? jnz AltWait ; Pressed? yes -> wait InitExit: pop ax ;Retrieve Return Status TRACER 'i' retn ;That's it for Init! ; *** start 1.4 changes at ded *** SpecGo: mov si,SpecPkt int 13h retn ScanDrives: push ax ; at df3 in 1.4 push si mov dl, 7fh ;Start at Drive 0x80 NextDrv: inc dl clc mov ax,4B01h ;Get Bootable CD-ROM Status mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt call SpecGo ; Carry is not cleared in buggy Dell BIOSes, ; so I'm checking packet size byte ; some bogus bioses (Dell Inspiron 2500) returns packet size 0xff when failed ; Dell Dimension XPsT returns packet size 0x14 when OK cmp BYTE [SpecPkt], 13h ; anything between 13h and 20h should be OK jb FindFail cmp BYTE [SpecPkt], 20h ja FindFail ; in 1.4 at e16 jmp short SendFound ; in 1.4 at e26 FindFail: cmp dl, 0ffh je SendFail ; Check from 80h..ffh jmp short NextDrv ;Next drive SendFail: xor dl,dl stc jmp short ThingDone SendFound: mov dl, [SpecPkt+2] clc ThingDone: pop si pop ax retn ; *** end 1.4 changes *** ;============================================================================= ;------------------------------------------------------------ ; keyboard flags - return keyboard flags in AL ; bit 3 = ALT key keyflag: ; at dbc in 1.3, at e2e in 1.4 push bx mov ah, 2 int 16h pop bx retn ;============================================================================= DrvNumMsg db ' Diskemxx.bin returned drive number=', 0 NoBootCD db ' No booted CD-ROM found.',CR,0 CDStat db ' INT 13h / AX=4B01h Specification Packet for ' db 'Booted CD-ROM:',CR,' ', 0 CDBytes db ' Drive ', 0 CDBytesA db ' returns ', 0 CDBytesB db 'h bytes per Sector.',CR,0 DevName db ' Device Name: ', 0 NoDevName db ' No Device Name found. ' db 'Usage: device=eltorito.sys /D:',CR,0 DrvInst db ' Driver ', 0 NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep DrvInst1 db 'installed',CR,0 WaitMsg db ' Alt pressed, waiting...', CR, 0 ;ContMsg db ' Continuing...' LineEnd db CR,0 ;=============================================================================