module: Allow .c32 files to execute themselves
[syslinux.git] / dosutil / eltorito.asm
blobd6b6b50e228474df6e21af2297b7cad637359d0f
2 ;-----------------------------------------------------------------------------
3 ; ElTorito.asm
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
8 ; MIT License
10 ; (c) 2000 by Gary Tong
11 ; (c) 2001-2009 by Bart Lagerweij
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:
20 ; The above copyright notice and this permission notice shall be included in
21 ; all copies or substantial portions of the Software.
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.
31 ;-----------------------------------------------------------------------------
33 ; To assemble and link, use these commands with NASM 2.x:
34 ; nasm -Ox -f bin -o eltorito.sys eltorito.asm
36 ; To enable Trace markers uncomment the line below
37 ; DEBUG_TRACERS=1
39 ; To enable debug info uncomment the line below
40 ; DEBUG=1
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
52 %define Ver '1.5'
53 %define CR 0DH, 0Ah
54 RPolyH equ 0EDB8h
55 RPolyL equ 08320h
57 section .text align=16
58 org 0
60 ;=============================================================================
62 Cdrom:
64 NextDriver dd -1 ;-+
65 Attributes dw 0C800h ; |
66 Pointers dw Strategy ; |
67 dw Commands ; | MSCDEX requires this
68 DeviceName db 'ELTORITO' ; | data in these locations
69 dw 0 ; |
70 DriveLetter db 0 ; |
71 NumUnitsSupp db 1 ;-+
73 DriverName db 'El-Torito CD-ROM Device Driver',0
74 align 4, db 0
75 ReqHdrLoc dd 0
76 XferAddr dd 0
77 Checksum dd -1
78 DriveNumber db 0
79 ReadBytes db 0 ;0 --> 2048 bytes/sector
80 ;1 --> 1024 bytes/sector
81 ;2 --> 512 bytes/sector
83 Routines dw Init ;Init ;0
84 dw Unsupported ;MediaCheck ;1
85 dw Unsupported ;BuildBPB ;2
86 dw IoctlInput ;IoctlInput ;3
87 dw Unsupported ;Input ;4
88 dw Unsupported ;NonDesInput ;5
89 dw Unsupported ;InputStatus ;6
90 dw Unsupported ;InputFlush ;7
91 dw Unsupported ;Output ;8
92 dw Unsupported ;OutputVerify ;9
93 dw Unsupported ;OutputStatus ;10
94 dw Unsupported ;OutputFlush ;11
95 dw IoctlOutput ;IoctlOutput ;12
96 dw DoNothing ;DeviceOpen ;13
97 dw DoNothing ;DeviceClose ;14
98 dw ReadL ;ReadL ;128
100 IoctlICtrl dw Raddr ;Raddr ;0
101 dw Unsupported ;LocHead ;1
102 dw Unsupported ;(Reserved) ;2
103 dw Unsupported ;ErrStat ;3
104 dw Unsupported ;AudInfo ;4
105 dw DrvBytes ;DrvBytes ;5
106 dw DevStat ;DevStat ;6
107 dw SectSize ;SectSize ;7
108 dw VolSize ;VolSize ;8
109 dw MedChng ;MedChng ;9
111 SpecPkt times 19 db 0 ; offset 77h in 1.4
112 times 13 db 0 ; unknown extra 00s in 1.4
114 Greeting db 'El-Torito Bootable CD-ROM Driver for Dos v',Ver,', http://www.nu2.nu/eltorito/',CR
115 db ' (c) 2000 by Gary Tong',CR
116 db ' (c) 2001-2002 by Bart Lagerweij',CR,0
117 DblSpace db ' ',0
119 ;=============================================================================
121 Strategy:
123 mov word [cs:ReqHdrLoc],bx
124 mov word [cs:ReqHdrLoc+2],es
125 retf
128 ;=============================================================================
130 Commands:
132 push ax
133 push bx
134 push cx
135 push dx
136 push si
137 push di
138 push bp
139 ; pushad
140 push ds
141 push es
142 TRACER 'C'
144 cld ;Clear direction
145 sti ;Enable interrupts
147 mov ax, cs ;ds=cs
148 mov ds, ax
150 les bx,[ReqHdrLoc] ;seg:offset ptr into es:bx
151 xor ax,ax
152 mov al,[es:bx+2] ;Get Command code
153 %ifdef DEBUG
154 call print_hex8
155 %endif
156 cmp al,15
157 jb Mult2 ;If 0-14
158 cmp al,128
159 jb UnknownCmd ;If 15-127
160 cmp al,129
161 jb ShiftDown ;If 128
162 UnknownCmd: mov al,121 ;8 = Unsupported (Reserved)
163 ShiftDown: sub al,113 ;128 --> 15, 121 --> 8
164 Mult2: shl al,1 ;Convert into offset (*2)
165 mov di,Routines
166 add di,ax
167 call word [di] ;Execute desired command
168 or ax,100h ;Set Return Status's Done bit
169 lds bx,[ReqHdrLoc] ;seg:offset ptr into ds:bx
170 mov [bx+3],ax ;Save Status
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
181 TRACER 'c'
182 pop es
183 pop ds
184 ; popad
185 pop bp
186 pop di
187 pop si
188 pop dx
189 pop cx
190 pop bx
191 pop ax
192 retf
195 ;=============================================================================
197 Unsupported: ;Unsupported Command
199 mov ax,8003h ;Set Status Error bit,
200 TRACER 'U'
201 TRACER 'C'
202 retn ; Error 3 = Unknown Command
205 ;=============================================================================
207 IoctlInput: ;IOCTL Input Routine
209 mov di,[es:bx+14] ;es:bx --> Request Header
210 mov es,[es:bx+16] ;Get Xfer Address into es:di
211 xor ax,ax ;Get Control Block Code
212 mov al,[es:di]
213 %ifdef DEBUG
214 TRACER 'I'
215 TRACER 'O'
216 call print_hex8
217 %endif
218 cmp al,10
219 jb UnkIoctlI ;If 0-9
220 mov al,2 ;Map to Unsupported
221 UnkIoctlI: shl al,1 ;Convert into offset (*2)
222 mov si,IoctlICtrl
223 add si,ax
224 call word [si] ;Execute desired command
225 retn
228 ;=============================================================================
230 Raddr: ;Return Device Header Address
232 TRACER 'A'
233 mov word [es:di+1],0
234 mov [es:di+3],cs
235 xor ax, ax ;Set Return Status = success
236 TRACER 'a'
237 retn
240 ;=============================================================================
242 DrvBytes: ;Read Drive Bytes
244 TRACER 'B'
245 push di ;Save original Xfer Addr
246 add di,2 ;Point to 1st dest byte
247 mov si,Greeting ;Point to Greeting
248 DrvB: movsb ;Copy over a byte
249 cmp byte [si],13 ;Is next char a CR?
250 jne DrvB ;Loop if not
252 sub di,2 ;Get #bytes copied into ax
253 mov ax,di
254 pop di ;Retrieve original Xfer Addr
255 sub ax,di
256 mov byte [es:di+1],al ;and save it
257 mov ax,0 ;Set Return Status = success
258 TRACER 'b'
259 retn
262 ;=============================================================================
264 DevStat: ;Return Device Status
266 TRACER 'D'
267 mov word [es:di+1],202h ;Door closed
268 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
278 xor ax, ax ;Set Return Status = success
279 TRACER 'd'
280 retn
283 ;=============================================================================
285 SectSize: ;Return Sector Size
287 TRACER 'S'
288 mov word [es:di+2],2048
289 mov ax,0 ;Set Return Status = success
290 TRACER 's'
291 retn
294 ;=============================================================================
296 VolSize: ;Return Volume Size
298 TRACER 'V'
299 call PriVolDesc ;Get and Check Primary Volume
300 ; Descriptor
301 mov ax,800Fh ;Assume Invalid Disk Change
302 jc VolExit ;If Read Failure
304 mov ax,word [Buffer+80] ;Read Successful
305 mov word [es:di+1],ax ;Copy over Volume Size
306 mov ax,word [Buffer+82]
307 mov word [es:di+3],ax
308 mov ax,0 ;Set Return Status = success
309 VolExit:
310 TRACER 'v'
311 retn
314 ;=============================================================================
316 MedChng: ;Return Media Changed Status
318 TRACER 'M'
319 call PriVolDesc ;Get and Check Primary Volume
320 ; Descriptor
321 mov byte [es:di+1],-1 ;Assume Media Changed
322 mov ax,800Fh ; and Invalid Disk Change
323 jc MedExit ;If Media Changed or Bad
325 mov byte [es:di+1],1 ;Media has not changed
326 mov ax,0 ;Set Return Status = success
327 MedExit:
328 TRACER 'm'
329 retn
332 ;=============================================================================
334 PriVolDesc: ;Get and Check Primary Volume
335 ; Descriptor
336 TRACER 'P'
337 mov ax,cs ;Set ds:si --> SpecPkt
338 mov ds,ax
340 mov cx, 5
341 PriVolAgain:
342 mov byte [SpecPkt],16 ;SpecPkt Size
343 mov byte [SpecPkt+1],0 ;Reserved
344 mov word [SpecPkt+2],1 ;Transfer one 2048-byte sector
345 push cx
346 mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512
347 shl word [SpecPkt+2],cl ; bytes at a time
348 pop cx
349 mov word [SpecPkt+6],cs ;Into our Buffer
350 mov word [SpecPkt+4], Buffer
351 mov word [SpecPkt+8],16 ;From CD Sector 16
352 mov word [SpecPkt+10],0
353 mov word [SpecPkt+12],0
354 mov word [SpecPkt+14],0
356 mov si, SpecPkt
357 mov dl, [DriveNumber]
358 mov ah, 42h ;Extended Read
359 int 13h
360 jnc PriVolPass ;If success
362 ; TRACER '1'
363 ; read error
364 loop PriVolAgain
366 TRACER '2'
367 ; read retries exhausted
368 ; flow into below
369 jmp PriReadErr
371 PriVolPass:
372 mov si,Buffer ;Point input to Buffer
373 mov ax,-1 ;Init Checksum registers
374 mov bx,ax ; bx,ax = 0FFFFFFFFh
375 jc PriNew ;If Read Failure
377 push di ;Read Successful,
378 ; so Calculate Checksum
379 mov di,1024 ;Init Word counter
380 PriWord: mov dx,[cs:si] ;Grab next word from buffer
381 mov cx,16 ;Init bit counter
382 PriBit: shr dx,1 ;Shift everything right 1 bit
383 rcr bx,1
384 rcr ax,1
385 jnc NoMult ;If a zero shifted out
387 xor bx,RPolyH ;A one shifted out, so XOR
388 xor ax,RPolyL ; Checksum with RPoly
389 NoMult:
390 loop PriBit
392 add si,2 ;Inc Word Pointer
393 dec di
394 ja PriWord
395 TRACER '3'
397 pop di ;Checksum calculation complete
398 cmp bx,[Checksum+2] ;Has Checksum changed?
399 jne PriNew ;If Checksum Changed
401 cmp ax,[Checksum]
402 jne PriNew ;If Checksum Changed
404 clc ;Checksum not changed, CF=0
405 mov ax,0 ;Status = success
406 jmp PriOld
408 PriReadErr:
409 mov WORD [Checksum+2],bx ;Save New Checksum
410 mov [Checksum],ax ; or 0FFFFFFFFh if bad read
411 stc ;Checksum change, CF=1
412 mov ax, 800bh ;Status = read fault
413 jmp PriOld
415 PriNew: mov WORD [Checksum+2],bx ;Save New Checksum
416 mov [Checksum],ax ; or 0FFFFFFFFh if bad read
417 stc ;Checksum Changed, CF=1
418 mov ax,800Fh ;Status = Invalid Media Change
419 PriOld:
420 TRACER 'p'
421 retn
424 ;=============================================================================
426 IoctlOutput: ;IOCTL Output Routine
428 TRACER 'O'
429 mov di,[es:bx+14] ;es:bx --> Request Header
430 mov es,[es:bx+16] ;Get Xfer Address into es:di
431 xor ax,ax ;Get Control Block Code
432 mov al,[es:di]
433 cmp al,2
434 jne UnkIoctlO ;If not 2 (ResetDrv)
435 call DoNothing ;Reset Drive
436 jmp IoctlODone
437 UnkIoctlO:
438 call Unsupported ;Unsupported command
439 IoctlODone:
440 TRACER 'o'
441 retn
444 ;=============================================================================
446 DoNothing: ;Do Nothing Command
448 mov ax,0 ;Set Return Status = success
449 retn
452 ;=============================================================================
454 ReadL: ;Read Long Command
456 TRACER 'R'
457 mov ax,cs ;Set ds=cs
458 mov ds,ax
459 ;es:bx --> Request Header
460 cmp byte [es:bx+24],0 ;Check Data Read Mode
461 jne ReadLErr ;If Cooked Mode
463 cmp byte [es:bx+13],2 ;Check Addressing Mode
464 jb ReadLOK ;If HSG or Redbook Mode
466 ReadLErr:
467 TRACER '8'
468 mov ax,8003h ;Set Return Status = Unknown
469 jmp ReadLExit ; Command Error and exit
471 ReadLOK:
472 mov ax,[es:bx+20] ;Get Starting Sector Number,
473 mov dx,[es:bx+22] ; Assume HSG Addressing Mode
474 cmp byte [es:bx+13],0 ;Check Addressing Mode again
475 je ReadLHSG ;If HSG Addressing Mode
477 TRACER '7'
478 ;Using Redbook Addressing Mode. Convert to HSG format
479 mov al,dl ;Get Minutes
480 mov dl,60
481 mul dl ;ax = Minutes * 60
482 add al,byte [es:bx+21] ;Add in Seconds
483 adc ah,0
484 mov dx,75 ;dx:ax =
485 mul dx ; ((Min * 60) + Sec) * 75
486 add al,byte [es:bx+20] ;Add in Frames
487 adc ah,0
488 adc dx,0
489 sub ax,150 ;Subtract 2-Second offset
490 sbb dx,0 ;dx:ax = HSG Starting Sector
492 ReadLHSG:
493 mov word [SpecPkt+8], ax ;Store Starting
494 mov word [SpecPkt+10], dx ; Sector Number
495 mov word [SpecPkt+12], 0 ; (HSG Format)
496 mov word [SpecPkt+14], 0
498 mov ax,[es:bx+14] ;Get Transfer Address
499 mov word [SpecPkt+4],ax
500 mov ax,[es:bx+16]
501 mov word [SpecPkt+6],ax
503 mov byte [SpecPkt],16 ;Size of Disk Address Packet
504 mov byte [SpecPkt+1],0 ;Reserved
506 mov cx, 5
507 ReadLAgain:
508 mov ax,[es:bx+18] ;Get number of sectors to read
509 mov word [SpecPkt+2],ax
510 cmp ax, 3FFFh ;Too large?
511 ja ReadLBad ;If yes
513 push cx
514 mov cl,byte [ReadBytes] ;Multiply by 4 if reading 512
515 shl word [SpecPkt+2],cl ; bytes at a time
516 pop cx
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 mov si,SpecPkt
535 mov dl,[DriveNumber]
536 mov ah,42h ;Extended Read
537 int 13h
538 jnc ReadLGd ;If success
540 ;hang:
541 ; jmp hang
542 ; TRACER '1'
543 loop ReadLAgain
544 TRACER '2'
545 jmp short ReadLBad
546 ReadLGd:
547 TRACER '3'
548 xor ax, ax ;Status 0 = success
549 jmp short ReadLExit
551 ReadLBad:
552 TRACER '9'
553 mov ax, 800Bh ;Set Read Fault Error
554 ; flow into ReadLExit
555 ReadLExit:
556 TRACER 'r'
557 retn
561 %ifdef DEBUG_TRACERS
562 debug_tracer: pushad
563 pushfd
565 mov al, '['
566 mov ah,0Eh ;BIOS video teletype output
567 xor bh, bh
568 int 10h ;Print it
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
575 mov ah,0Eh ;BIOS video teletype output
576 xor bh, bh
577 int 10h ;Print it
579 mov al, ']'
580 mov ah,0Eh ;BIOS video teletype output
581 xor bh, bh
582 int 10h ;Print it
584 popfd
585 popad
586 retn
587 %endif
589 ;-----------------------------------------------------------------------------
590 ; PRINT_HEX4
591 ;-----------------------------------------------------------------------------
592 ; print a 4 bits integer in hex
594 ; Input:
595 ; AL - 4 bits integer to print (low)
597 ; Output: None
599 ; Registers destroyed: None
601 print_hex4:
603 push ax
604 and al, 0fh ; we only need the first nibble
605 cmp al, 10
606 jae hex_A_F
607 add al, '0'
608 jmp hex_0_9
609 hex_A_F:
610 add al, 'A'-10
611 hex_0_9:
612 call print_char
613 pop ax
614 retn
617 ;-----------------------------------------------------------------------------
618 ; print_hex8
619 ;-----------------------------------------------------------------------------
620 ; print a 8 bits integer in hex
622 ; Input:
623 ; AL - 8 bits integer to print
625 ; Output: None
627 ; Registers destroyed: None
629 print_hex8:
631 push ax
632 push bx
634 mov ah, al
635 shr al, 4
636 call print_hex4
638 mov al, ah
639 and al, 0fh
640 call print_hex4
642 pop bx
643 pop ax
644 retn
647 ;=============================================================================
648 ; print_hex16 - print a 16 bits integer in hex
650 ; Input:
651 ; AX - 16 bits integer to print
653 ; Output: None
655 ; Registers destroyed: None
656 ;=============================================================================
657 print_hex16:
659 push ax
660 push bx
661 push cx
663 mov cx, 4
664 print_hex16_loop:
665 rol ax, 4
666 call print_hex4
667 loop print_hex16_loop
669 pop cx
670 pop bx
671 pop ax
672 retn
674 ;=============================================================================
675 ; print_hex32 - print a 32 bits integer in hex
677 ; Input:
678 ; EAX - 32 bits integer to print
680 ; Output: None
682 ; Registers destroyed: None
683 ;=============================================================================
684 print_hex32:
686 push eax
687 push bx
688 push cx
690 mov cx, 8
691 print_hex32_loop:
692 rol eax, 4
693 call print_hex4
694 loop print_hex32_loop
696 pop cx
697 pop bx
698 pop eax
699 retn
701 ;=============================================================================
702 ; print_string - print string at current cursor location
704 ; Input:
705 ; DS:SI - ASCIIZ string to print
707 ; Output: None
709 ; Registers destroyed: None
710 ;=============================================================================
711 print_string:
712 push ax
713 push si
715 print_string_again:
716 mov al, [si]
717 or al, al
718 jz print_string_exit
719 call print_char
720 inc si
721 jmp print_string_again
723 print_string_exit:
724 pop si
725 pop ax
726 retn
728 ;-----------------------------------------------------------------------------
729 ; PRINT_CHAR
730 ;-----------------------------------------------------------------------------
731 ; Print's a character at current cursor position
733 ; Input:
734 ; AL - Character to print
736 ; Output: None
738 ; Registers destroyed: None
740 print_char:
742 push ax
743 push bx
745 mov ah,0Eh ;BIOS video teletype output
746 xor bh, bh
747 int 10h ;Print it
749 print_char_exit:
750 pop bx
751 pop ax
752 retn
755 ;=============================================================================
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
761 align 16, db 0
762 Buffer times 2049 db 96h
764 ;=============================================================================
766 Init: ;Initialization Routine
768 TRACER 'I'
769 mov ax,cs ;ds=cs
770 mov ds,ax
772 %ifdef DEBUG
773 ; print CS value (load segment)
774 call print_hex16
775 %endif
777 mov si, Greeting ;Display Greeting
778 call print_string
780 mov ax,Unsupported ;Init is executed only once
781 mov [Routines],ax
783 mov ax, 5400h
784 int 13h ; Get diskemu status
785 jc FindBoot ; If CF=1 no diskemu loaded
787 mov [DriveNumber], cl ; Store drive number
789 call keyflag
790 and al, 8 ; alt key ?
791 jz extread
793 mov si, DrvNumMsg ; Display "drive number="
794 call print_string
795 mov al, [DriveNumber]
796 call print_hex8
797 mov si, LineEnd ; CR/LF
798 call print_string
799 jmp extread
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 FindBoot: call ScanDrives ; call new helper in 1.4
807 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
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
819 ; cmp [SpecPkt], 0
820 ; jne FoundBoot
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
828 ; FindFail:
829 ; dec dl ;Next drive
830 ; cmp dl, 80h
831 ; jae FindBoot ;Check from ffh..80h
832 ; *** end of 1.4 changes ***
834 mov si,NoBootCD ;No booted CD found,
835 call print_string
836 jmp NoEndAddr ;Do not install driver
838 FoundBoot:
839 ; mov dl, [SpecPkt+2] ; 1.4 change
840 ; *** next line at c57 in 1.4, at c3d in 1.3 ***
841 mov [DriveNumber],dl ;Booted CD-ROM found,
842 ; so save Drive #
844 call keyflag
845 and al, 8 ; alt key ?
846 jz extread
848 mov si, CDStat
849 call print_string
850 mov si, SpecPkt ;Point to returned CD SpecPkt
851 mov cx, 19 ; containing 19 bytes
852 StatDump: mov al, ' ' ;Print a space
853 call print_char
854 mov al, byte [si] ;Hexdump a SpecPkt byte
855 call print_hex8
856 inc si ;Point to next byte
857 loop StatDump
859 mov si, LineEnd ;Print a CR/LF
860 call print_string
862 extread:
863 ;See how many CD Sector bytes are returned by an Extended Read
864 mov byte [SpecPkt],16 ;SpecPkt Size
865 mov byte [SpecPkt+1],0 ;Reserved
866 mov word [SpecPkt+2],1 ;Transfer one sector
867 mov word [SpecPkt+6],cs ;Into our Buffer
868 mov word [SpecPkt+4],Buffer
869 mov word [SpecPkt+8],16 ;From CD Sector 16
870 mov word [SpecPkt+10],0
871 mov word [SpecPkt+12],0
872 mov word [SpecPkt+14],0
874 mov si, SpecPkt ;Set ds:si --> SpecPkt
875 mov dl, [DriveNumber]
876 mov ah, 42h ;Extended Read
877 int 13h
878 jnc SecSize ;If success
880 mov ah, 42h ;Always make 2 read attempts
881 int 13h
882 ;How many bytes did we get?
883 SecSize: std ;Count down
884 mov ax,cs ;Point to end of Buffer
885 mov es,ax
886 mov di,Buffer+2047 ;Find end of read data
887 mov si,Buffer+2048
888 mov cx,2049
889 repe cmpsb ;cx = number of bytes read
891 cld ;Restore count direction to up
892 mov si,CDBytes ;Display number of bytes read
893 call print_string
895 mov al, [DriveNumber]
896 call print_hex8
898 mov si,CDBytesA ;Remainder A of message
899 call print_string
901 mov al,ch ;Hex-dump cx
902 and al,0Fh ;Second nibble
903 call print_hex8 ; (don't need the First)
904 mov al,cl
905 call print_hex8 ; (don't need the First)
907 mov si,CDBytesB ;Remainder B of message
908 call print_string
910 cmp cx,2048 ;Did we read 2048 bytes?
911 je ParseParm ;If yes <-- O.K.
913 mov byte [ReadBytes],1
914 cmp cx,1024 ;Did we read 1024 bytes?
915 je ParseParm ;If yes <-- O.K.
917 mov byte [ReadBytes],2
918 cmp cx,512 ;Did we read 512 bytes?
919 jne NoEndAddr ;If not, do not load driver
921 ParseParm: mov bx,word [cs:ReqHdrLoc] ;Parse command line
922 mov es,word [cs:ReqHdrLoc+2] ; parameters
923 mov si,[es:bx+18] ;Get BPB array ptr into DS:SI
924 mov ds,[es:bx+20]
925 FindParm: inc si
926 FindParm1: cmp byte [si],0Dh ;CR? (End of parameters)
927 je EndOfParms
929 cmp byte [si],0Ah ;LF?
930 je EndOfParms
932 cmp byte [si],'/' ;A parameter?
933 jne FindParm
935 inc si
936 cmp byte [si],'D' ;Device Name parameter?
937 jne FindParm1
939 inc si
940 cmp byte [si],':'
941 jne FindParm1
943 ;bbb
944 push si
945 mov si, DevName ;Device Name is at ds:si
946 push ds ;Keep ptr to Device Name
947 mov ax, cs
948 mov ds, ax
949 call print_string
950 pop ds ;Retrieve Device Name ptr
951 pop si
952 mov cx, 8 ;Get next 8 chars
953 inc si ; = Device Name
954 mov ax, cs
955 mov es, ax
956 mov di, DeviceName
957 NextChar: cmp byte [si],' '
958 ja AboveSpace
960 mov ax,cs ;Pad end of Device Name with
961 mov ds,ax ; spaces if necessary
962 mov si,DblSpace ;A space
963 AboveSpace: mov al, [si]
964 call print_char
965 movsb ;ds:[si] --> es:[di]
966 loop NextChar
968 mov si,LineEnd
969 mov ax,cs
970 mov ds,ax
971 call print_string
973 mov ax,Init-2 ;Last byte of driver to keep
974 jmp EndAddr ;Install driver
976 EndOfParms:
977 mov ax, cs ; Restore segment registers (fix)
978 mov ds, ax
979 mov es, ax
981 mov si,NoDevName ;No Device Name Found
982 call print_string
984 NoEndAddr: mov ax,0 ;Do not install driver
986 EndAddr: mov es,[ReqHdrLoc+2] ;Write End Address
987 mov bx,[ReqHdrLoc]
988 mov [es:bx+14],ax
989 mov [es:bx+16],cs
990 mov bx,ax ;Hold onto install status
992 mov si, DrvInst ;Display driver install status
993 call print_string
994 mov si, DrvInst1 ;Assume driver installed
995 cmp bx,0 ;Was driver installed?
996 jne DrvStatus ;If yes
997 mov si, NoDrvInst ;Driver not installed
998 DrvStatus: call print_string
1000 mov ax,0 ;Set Return Status = success
1001 cmp bx,0 ;Was INIT successful?
1002 jne InitStat ;If yes
1003 mov ax,800Ch ;Status = General Failure
1004 InitStat:
1005 push ax ;Save Return Status
1007 call keyflag
1008 and al, 8 ; alt key ?
1009 jz InitExit
1011 WaitHere:
1012 mov si, WaitMsg ;Display Halted message
1013 call print_string
1015 AltWait:
1016 call keyflag
1017 and al, 8 ; Alt key?
1018 jnz AltWait ; Pressed? yes -> wait
1020 InitExit:
1021 pop ax ;Retrieve Return Status
1022 TRACER 'i'
1023 retn ;That's it for Init!
1025 ; *** start 1.4 changes at ded ***
1026 SpecGo: mov si,SpecPkt
1027 int 13h
1028 retn
1030 ScanDrives: push ax ; at df3 in 1.4
1031 push si
1032 mov dl, 7fh ;Start at Drive 0x80
1033 NextDrv: inc dl
1035 mov ax,4B01h ;Get Bootable CD-ROM Status
1036 mov BYTE [SpecPkt],0 ;Clear 1st byte of SpecPkt
1037 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
1043 cmp BYTE [SpecPkt], 13h ; anything between 13h and 20h should be OK
1044 jb FindFail
1045 cmp BYTE [SpecPkt], 20h
1046 ja FindFail ; in 1.4 at e16
1047 jmp short SendFound ; in 1.4 at e26
1049 FindFail: cmp dl, 0ffh
1050 je SendFail ; Check from 80h..ffh
1051 jmp short NextDrv ;Next drive
1052 SendFail: xor dl,dl
1054 jmp short ThingDone
1055 SendFound: mov dl, [SpecPkt+2]
1057 ThingDone: pop si
1058 pop ax
1059 retn
1060 ; *** end 1.4 changes ***
1062 ;=============================================================================
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 push bx
1069 mov ah, 2
1070 int 16h
1071 pop bx
1072 retn
1074 ;=============================================================================
1076 DrvNumMsg db ' Diskemxx.bin returned drive number=', 0
1077 NoBootCD db ' No booted CD-ROM found.',CR,0
1079 CDStat db ' INT 13h / AX=4B01h Specification Packet for '
1080 db 'Booted CD-ROM:',CR,' ', 0
1082 CDBytes db ' Drive ', 0
1083 CDBytesA db ' returns ', 0
1084 CDBytesB db 'h bytes per Sector.',CR,0
1086 DevName db ' Device Name: ', 0
1087 NoDevName db ' No Device Name found. '
1088 db 'Usage: device=eltorito.sys /D:<DevName>',CR,0
1090 DrvInst db ' Driver ', 0
1091 NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep
1092 DrvInst1 db 'installed',CR,0
1094 WaitMsg db ' Alt pressed, waiting...', CR, 0
1095 ;ContMsg db ' Continuing...'
1096 LineEnd db CR,0
1099 ;=============================================================================