blob: d6b6b50e228474df6e21af2297b7cad637359d0f [file] [log] [blame]
Greg Hartman76d05dc2016-11-23 15:51:27 -08001
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
54RPolyH equ 0EDB8h
55RPolyL equ 08320h
56
57 section .text align=16
58 org 0
59
60;=============================================================================
61
62Cdrom:
63
64NextDriver dd -1 ;-+
65Attributes dw 0C800h ; |
66Pointers dw Strategy ; |
67 dw Commands ; | MSCDEX requires this
68DeviceName db 'ELTORITO' ; | data in these locations
69 dw 0 ; |
70DriveLetter db 0 ; |
71NumUnitsSupp db 1 ;-+
72
73DriverName db 'El-Torito CD-ROM Device Driver',0
74 align 4, db 0
75ReqHdrLoc dd 0
76XferAddr dd 0
77Checksum dd -1
78DriveNumber db 0
79ReadBytes db 0 ;0 --> 2048 bytes/sector
80 ;1 --> 1024 bytes/sector
81 ;2 --> 512 bytes/sector
82
83Routines 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
99
100IoctlICtrl 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
110
111SpecPkt times 19 db 0 ; offset 77h in 1.4
112 times 13 db 0 ; unknown extra 00s in 1.4
113
114Greeting 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
117DblSpace db ' ',0
118
119;=============================================================================
120
121Strategy:
122
123 mov word [cs:ReqHdrLoc],bx
124 mov word [cs:ReqHdrLoc+2],es
125 retf
126
127
128;=============================================================================
129
130Commands:
131
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'
143
144 cld ;Clear direction
145 sti ;Enable interrupts
146
147 mov ax, cs ;ds=cs
148 mov ds, ax
149
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
162UnknownCmd: mov al,121 ;8 = Unsupported (Reserved)
163ShiftDown: sub al,113 ;128 --> 15, 121 --> 8
164Mult2: 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
171
172%ifdef DEBUG
173 cmp byte [cs:buffer+2048], 96h
174 je buffer_ok
175 mov al, '!'
176 call print_char
177 jmp $
178buffer_ok:
179%endif
180
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
193
194
195;=============================================================================
196
197Unsupported: ;Unsupported Command
198
199 mov ax,8003h ;Set Status Error bit,
200 TRACER 'U'
201 TRACER 'C'
202 retn ; Error 3 = Unknown Command
203
204
205;=============================================================================
206
207IoctlInput: ;IOCTL Input Routine
208
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
221UnkIoctlI: shl al,1 ;Convert into offset (*2)
222 mov si,IoctlICtrl
223 add si,ax
224 call word [si] ;Execute desired command
225 retn
226
227
228;=============================================================================
229
230Raddr: ;Return Device Header Address
231
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
238
239
240;=============================================================================
241
242DrvBytes: ;Read Drive Bytes
243
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
248DrvB: movsb ;Copy over a byte
249 cmp byte [si],13 ;Is next char a CR?
250 jne DrvB ;Loop if not
251
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
260
261
262;=============================================================================
263
264DevStat: ;Return Device Status
265
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
277
278 xor ax, ax ;Set Return Status = success
279 TRACER 'd'
280 retn
281
282
283;=============================================================================
284
285SectSize: ;Return Sector Size
286
287 TRACER 'S'
288 mov word [es:di+2],2048
289 mov ax,0 ;Set Return Status = success
290 TRACER 's'
291 retn
292
293
294;=============================================================================
295
296VolSize: ;Return Volume Size
297
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
303
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
309VolExit:
310 TRACER 'v'
311 retn
312
313
314;=============================================================================
315
316MedChng: ;Return Media Changed Status
317
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
324
325 mov byte [es:di+1],1 ;Media has not changed
326 mov ax,0 ;Set Return Status = success
327MedExit:
328 TRACER 'm'
329 retn
330
331
332;=============================================================================
333
334PriVolDesc: ;Get and Check Primary Volume
335 ; Descriptor
336 TRACER 'P'
337 mov ax,cs ;Set ds:si --> SpecPkt
338 mov ds,ax
339
340 mov cx, 5
341PriVolAgain:
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
355
356 mov si, SpecPkt
357 mov dl, [DriveNumber]
358 mov ah, 42h ;Extended Read
359 int 13h
360 jnc PriVolPass ;If success
361
362; TRACER '1'
363 ; read error
364 loop PriVolAgain
365
366 TRACER '2'
367 ; read retries exhausted
368 ; flow into below
369 jmp PriReadErr
370
371PriVolPass:
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
376
377 push di ;Read Successful,
378 ; so Calculate Checksum
379 mov di,1024 ;Init Word counter
380PriWord: mov dx,[cs:si] ;Grab next word from buffer
381 mov cx,16 ;Init bit counter
382PriBit: shr dx,1 ;Shift everything right 1 bit
383 rcr bx,1
384 rcr ax,1
385 jnc NoMult ;If a zero shifted out
386
387 xor bx,RPolyH ;A one shifted out, so XOR
388 xor ax,RPolyL ; Checksum with RPoly
389NoMult:
390 loop PriBit
391
392 add si,2 ;Inc Word Pointer
393 dec di
394 ja PriWord
395 TRACER '3'
396
397 pop di ;Checksum calculation complete
398 cmp bx,[Checksum+2] ;Has Checksum changed?
399 jne PriNew ;If Checksum Changed
400
401 cmp ax,[Checksum]
402 jne PriNew ;If Checksum Changed
403
404 clc ;Checksum not changed, CF=0
405 mov ax,0 ;Status = success
406 jmp PriOld
407
408PriReadErr:
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
414
415PriNew: 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
419PriOld:
420 TRACER 'p'
421 retn
422
423
424;=============================================================================
425
426IoctlOutput: ;IOCTL Output Routine
427
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
437UnkIoctlO:
438 call Unsupported ;Unsupported command
439IoctlODone:
440 TRACER 'o'
441 retn
442
443
444;=============================================================================
445
446DoNothing: ;Do Nothing Command
447
448 mov ax,0 ;Set Return Status = success
449 retn
450
451
452;=============================================================================
453
454ReadL: ;Read Long Command
455
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
462
463 cmp byte [es:bx+13],2 ;Check Addressing Mode
464 jb ReadLOK ;If HSG or Redbook Mode
465
466ReadLErr:
467 TRACER '8'
468 mov ax,8003h ;Set Return Status = Unknown
469 jmp ReadLExit ; Command Error and exit
470
471ReadLOK:
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
476
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
491
492ReadLHSG:
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
497
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
502
503 mov byte [SpecPkt],16 ;Size of Disk Address Packet
504 mov byte [SpecPkt+1],0 ;Reserved
505
506 mov cx, 5
507ReadLAgain:
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
512
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
517
518%ifdef DEBUG
519 push ax
520 push cx
521 push si
522 mov cx, 16
523 mov si,SpecPkt
524ReadDump: 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
539
540;hang:
541; jmp hang
542; TRACER '1'
543 loop ReadLAgain
544 TRACER '2'
545 jmp short ReadLBad
546ReadLGd:
547 TRACER '3'
548 xor ax, ax ;Status 0 = success
549 jmp short ReadLExit
550
551ReadLBad:
552 TRACER '9'
553 mov ax, 800Bh ;Set Read Fault Error
554 ; flow into ReadLExit
555ReadLExit:
556 TRACER 'r'
557 retn
558
559
560
561%ifdef DEBUG_TRACERS
562debug_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;
601print_hex4:
602
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
609hex_A_F:
610 add al, 'A'-10
611hex_0_9:
612 call print_char
613 pop ax
614 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;
629print_hex8:
630
631 push ax
632 push bx
633
634 mov ah, al
635 shr al, 4
636 call print_hex4
637
638 mov al, ah
639 and al, 0fh
640 call print_hex4
641
642 pop bx
643 pop ax
644 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;=============================================================================
657print_hex16:
658
659 push ax
660 push bx
661 push cx
662
663 mov cx, 4
664print_hex16_loop:
665 rol ax, 4
666 call print_hex4
667 loop print_hex16_loop
668
669 pop cx
670 pop bx
671 pop ax
672 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;=============================================================================
684print_hex32:
685
686 push eax
687 push bx
688 push cx
689
690 mov cx, 8
691print_hex32_loop:
692 rol eax, 4
693 call print_hex4
694 loop print_hex32_loop
695
696 pop cx
697 pop bx
698 pop eax
699 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;=============================================================================
711print_string:
712 push ax
713 push si
714
715print_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
722
723print_string_exit:
724 pop si
725 pop ax
726 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;
740print_char:
741
742 push ax
743 push bx
744
745 mov ah,0Eh ;BIOS video teletype output
746 xor bh, bh
747 int 10h ;Print it
748
749print_char_exit:
750 pop bx
751 pop ax
752 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 align 16, db 0
762Buffer times 2049 db 96h
763
764;=============================================================================
765
766Init: ;Initialization Routine
767
768 TRACER 'I'
769 mov ax,cs ;ds=cs
770 mov ds,ax
771
772%ifdef DEBUG
773; print CS value (load segment)
774 call print_hex16
775%endif
776
777 mov si, Greeting ;Display Greeting
778 call print_string
779
780 mov ax,Unsupported ;Init is executed only once
781 mov [Routines],ax
782
783 mov ax, 5400h
784 int 13h ; Get diskemu status
785 jc FindBoot ; If CF=1 no diskemu loaded
786
787 mov [DriveNumber], cl ; Store drive number
788
789 call keyflag
790 and al, 8 ; alt key ?
791 jz extread
792
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
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 ***
806FindBoot: 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
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 mov si,NoBootCD ;No booted CD found,
835 call print_string
836 jmp NoEndAddr ;Do not install driver
837
838FoundBoot:
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 #
843
844 call keyflag
845 and al, 8 ; alt key ?
846 jz extread
847
848 mov si, CDStat
849 call print_string
850 mov si, SpecPkt ;Point to returned CD SpecPkt
851 mov cx, 19 ; containing 19 bytes
852StatDump: 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
858
859 mov si, LineEnd ;Print a CR/LF
860 call print_string
861
862extread:
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
873
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
879
880 mov ah, 42h ;Always make 2 read attempts
881 int 13h
882 ;How many bytes did we get?
883SecSize: 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
890
891 cld ;Restore count direction to up
892 mov si,CDBytes ;Display number of bytes read
893 call print_string
894
895 mov al, [DriveNumber]
896 call print_hex8
897
898 mov si,CDBytesA ;Remainder A of message
899 call print_string
900
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)
906
907 mov si,CDBytesB ;Remainder B of message
908 call print_string
909
910 cmp cx,2048 ;Did we read 2048 bytes?
911 je ParseParm ;If yes <-- O.K.
912
913 mov byte [ReadBytes],1
914 cmp cx,1024 ;Did we read 1024 bytes?
915 je ParseParm ;If yes <-- O.K.
916
917 mov byte [ReadBytes],2
918 cmp cx,512 ;Did we read 512 bytes?
919 jne NoEndAddr ;If not, do not load driver
920
921ParseParm: 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]
925FindParm: inc si
926FindParm1: cmp byte [si],0Dh ;CR? (End of parameters)
927 je EndOfParms
928
929 cmp byte [si],0Ah ;LF?
930 je EndOfParms
931
932 cmp byte [si],'/' ;A parameter?
933 jne FindParm
934
935 inc si
936 cmp byte [si],'D' ;Device Name parameter?
937 jne FindParm1
938
939 inc si
940 cmp byte [si],':'
941 jne FindParm1
942
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
957NextChar: cmp byte [si],' '
958 ja AboveSpace
959
960 mov ax,cs ;Pad end of Device Name with
961 mov ds,ax ; spaces if necessary
962 mov si,DblSpace ;A space
963AboveSpace: mov al, [si]
964 call print_char
965 movsb ;ds:[si] --> es:[di]
966 loop NextChar
967
968 mov si,LineEnd
969 mov ax,cs
970 mov ds,ax
971 call print_string
972
973 mov ax,Init-2 ;Last byte of driver to keep
974 jmp EndAddr ;Install driver
975
976EndOfParms:
977 mov ax, cs ; Restore segment registers (fix)
978 mov ds, ax
979 mov es, ax
980
981 mov si,NoDevName ;No Device Name Found
982 call print_string
983
984NoEndAddr: mov ax,0 ;Do not install driver
985
986EndAddr: 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
991
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
998DrvStatus: call print_string
999
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
1004InitStat:
1005 push ax ;Save Return Status
1006
1007 call keyflag
1008 and al, 8 ; alt key ?
1009 jz InitExit
1010
1011WaitHere:
1012 mov si, WaitMsg ;Display Halted message
1013 call print_string
1014
1015AltWait:
1016 call keyflag
1017 and al, 8 ; Alt key?
1018 jnz AltWait ; Pressed? yes -> wait
1019
1020InitExit:
1021 pop ax ;Retrieve Return Status
1022 TRACER 'i'
1023 retn ;That's it for Init!
1024
1025 ; *** start 1.4 changes at ded ***
1026SpecGo: mov si,SpecPkt
1027 int 13h
1028 retn
1029
1030ScanDrives: push ax ; at df3 in 1.4
1031 push si
1032 mov dl, 7fh ;Start at Drive 0x80
1033NextDrv: inc dl
1034 clc
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
1042
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
1048
1049FindFail: cmp dl, 0ffh
1050 je SendFail ; Check from 80h..ffh
1051 jmp short NextDrv ;Next drive
1052SendFail: xor dl,dl
1053 stc
1054 jmp short ThingDone
1055SendFound: mov dl, [SpecPkt+2]
1056 clc
1057ThingDone: pop si
1058 pop ax
1059 retn
1060 ; *** end 1.4 changes ***
1061
1062;=============================================================================
1063
1064;------------------------------------------------------------
1065; keyboard flags - return keyboard flags in AL
1066; bit 3 = ALT key
1067keyflag: ; 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
1073
1074;=============================================================================
1075
1076DrvNumMsg db ' Diskemxx.bin returned drive number=', 0
1077NoBootCD db ' No booted CD-ROM found.',CR,0
1078
1079CDStat db ' INT 13h / AX=4B01h Specification Packet for '
1080 db 'Booted CD-ROM:',CR,' ', 0
1081
1082CDBytes db ' Drive ', 0
1083CDBytesA db ' returns ', 0
1084CDBytesB db 'h bytes per Sector.',CR,0
1085
1086DevName db ' Device Name: ', 0
1087NoDevName db ' No Device Name found. '
1088 db 'Usage: device=eltorito.sys /D:<DevName>',CR,0
1089
1090DrvInst db ' Driver ', 0
1091NoDrvInst db 7,'not ' ;7 = Ctrl-G = Beep
1092DrvInst1 db 'installed',CR,0
1093
1094WaitMsg db ' Alt pressed, waiting...', CR, 0
1095;ContMsg db ' Continuing...'
1096LineEnd db CR,0
1097
1098
1099;=============================================================================