Added the original copyright from isolinux.
[reactos.git] / freeldr / bootsect / isoboot.asm
1 ; ****************************************************************************
2 ;
3 ; isolinux.asm
4 ;
5 ; A program to boot Linux kernels off a CD-ROM using the El Torito
6 ; boot standard in "no emulation" mode, making the entire filesystem
7 ; available. It is based on the SYSLINUX boot loader for MS-DOS
8 ; floppies.
9 ;
10 ; Copyright (C) 1994-2001 H. Peter Anvin
11 ;
12 ; This program is free software; you can redistribute it and/or modify
13 ; it under the terms of the GNU General Public License as published by
14 ; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
15 ; USA; either version 2 of the License, or (at your option) any later
16 ; version; incorporated herein by reference.
17 ;
18 ; ****************************************************************************
19 ;
20 ; THIS FILE IS A MODIFIED VERSION OF ISOLINUX.ASM
21 ; MODIFICATION DONE BY MICHAEL K TER LOUW
22 ; LAST UPDATED 3-9-2002
23 ; SEE "COPYING" FOR INFORMATION ABOUT THE LICENSE THAT APPLIES TO THIS RELEASE
24 ;
25 ; ****************************************************************************
26 ;
27 ; This file is a modified version of ISOLINUX.ASM.
28 ; Modification done by Eric Kohl
29 ; Last update 04-25-2002
30 ;
31 ; ****************************************************************************
32
33 ; Note: The Makefile builds one version with DEBUG_MESSAGES automatically.
34 ;%define DEBUG_MESSAGES ; Uncomment to get debugging messages
35
36
37
38
39 ; ---------------------------------------------------------------------------
40 ; BEGIN THE BIOS/CODE/DATA SEGMENT
41 ; ---------------------------------------------------------------------------
42
43 absolute 0400h
44 serial_base resw 4 ; Base addresses for 4 serial ports
45 absolute 0413h
46 BIOS_fbm resw 1 ; Free Base Memory (kilobytes)
47 absolute 046Ch
48 BIOS_timer resw 1 ; Timer ticks
49 absolute 0472h
50 BIOS_magic resw 1 ; BIOS reset magic
51 absolute 0484h
52 BIOS_vidrows resb 1 ; Number of screen rows
53
54 ;
55 ; Memory below this point is reserved for the BIOS and the MBR
56 ;
57 absolute 1000h
58 trackbuf resb 8192 ; Track buffer goes here
59 trackbufsize equ $-trackbuf
60 ; trackbuf ends at 3000h
61
62 struc open_file_t
63 file_sector resd 1 ; Sector pointer (0 = structure free)
64 file_left resd 1 ; Number of sectors left
65 endstruc
66
67 struc dir_t
68 dir_lba resd 1 ; Directory start (LBA)
69 dir_len resd 1 ; Length in bytes
70 dir_clust resd 1 ; Length in clusters
71 endstruc
72
73
74 MAX_OPEN_LG2 equ 2 ; log2(Max number of open files)
75 MAX_OPEN equ (1 << MAX_OPEN_LG2)
76 SECTORSIZE_LG2 equ 11 ; 2048 bytes/sector (El Torito requirement)
77 SECTORSIZE equ (1 << SECTORSIZE_LG2)
78 CR equ 13 ; Carriage Return
79 LF equ 10 ; Line Feed
80
81
82
83 absolute 5000h ; Here we keep our BSS stuff
84
85 DriveNo resb 1 ; CD-ROM BIOS drive number
86 DiskError resb 1 ; Error code for disk I/O
87 RetryCount resb 1 ; Used for disk access retries
88 TimeoutCount resb 1 ; Timeout counter
89 ISOFlags resb 1 ; Flags for ISO directory search
90 RootDir resb dir_t_size ; Root directory
91 CurDir resb dir_t_size ; Current directory
92 ISOFileName resb 64 ; ISO filename canonicalization buffer
93 ISOFileNameEnd equ $
94
95
96 alignb open_file_t_size
97 Files resb MAX_OPEN*open_file_t_size
98
99
100
101 section .text
102 org 7000h
103
104 start:
105 cli ; Disable interrupts
106 xor ax, ax ; ax = segment zero
107 mov ss, ax ; Initialize stack segment
108 mov sp, start ; Set up stack
109 mov ds, ax ; Initialize other segment registers
110 mov es, ax
111 mov fs, ax
112 mov gs, ax
113 sti ; Enable interrupts
114 cld ; Increment pointers
115
116 mov cx, 2048 >> 2 ; Copy the bootsector
117 mov si, 0x7C00 ; from 0000:7C00
118 mov di, 0x7000 ; to 0000:7000
119 rep movsd ; copy the program
120 jmp 0:relocate ; jump into relocated code
121
122 relocate:
123 ; Display the banner and copyright
124 %ifdef DEBUG_MESSAGES
125 mov si, isolinux_banner ; si points to hello message
126 call writestr ; display the message
127 mov si,copyright_str
128 call writestr
129 %endif
130
131
132 ; Make sure the keyboard buffer is empty
133 .kbd_buffer_test:
134 call pollchar
135 jz .kbd_buffer_empty
136 call getchar
137 jmp .kbd_buffer_test
138 .kbd_buffer_empty:
139
140 ; Display the 'Press key' message and wait for a maximum of 5 seconds
141 call crlf
142 mov si, presskey_msg ; si points to 'Press key' message
143 call writestr ; display the message
144
145 mov byte [TimeoutCount], 5
146 .next_second:
147 mov eax, [BIOS_timer] ; load current tick counter
148 add eax, 19 ;
149
150 .poll_again:
151 call pollchar
152 jnz .boot_cdrom
153
154 mov ebx, [BIOS_timer]
155 cmp eax, ebx
156 jnz .poll_again
157
158 mov si, dot_msg ; print '.'
159 call writestr
160 dec byte [TimeoutCount] ; decrement timeout counter
161 jz .boot_harddisk
162 jmp .next_second
163
164 .boot_harddisk:
165 ; Boot first harddisk (drive 0x80)
166 mov ax, 0201h
167 mov dx, 0080h
168 mov cx, 0001h
169 mov bx, 7C00h
170 int 13h
171 jnc .go_hd
172 jmp kaboom
173 .go_hd:
174 mov ax, cs
175 mov ds, ax
176 mov es, ax
177 mov fs, ax
178 mov gs, ax
179 mov dx, 0080h
180
181 jmp 0:0x7C00
182
183
184 .boot_cdrom:
185 ; Save and display the boot drive number
186 mov [DriveNo], dl
187 %ifdef DEBUG_MESSAGES
188 mov si, startup_msg
189 call writemsg
190 mov al, dl
191 call writehex2
192 call crlf
193 %endif
194
195 ; Now figure out what we're actually doing
196 ; Note: use passed-in DL value rather than 7Fh because
197 ; at least some BIOSes will get the wrong value otherwise
198 mov ax, 4B01h ; Get disk emulation status
199 mov dl, [DriveNo]
200 mov si, spec_packet
201 int 13h
202 jc near spec_query_failed ; Shouldn't happen (BIOS bug)
203 mov dl, [DriveNo]
204 cmp [sp_drive], dl ; Should contain the drive number
205 jne near spec_query_failed
206
207 %ifdef DEBUG_MESSAGES
208 mov si, spec_ok_msg
209 call writemsg
210 mov al, byte [sp_drive]
211 call writehex2
212 call crlf
213 %endif
214
215 found_drive:
216 ; Get drive information
217 mov ah, 48h
218 mov dl, [DriveNo]
219 mov si, drive_params
220 int 13h
221 jnc params_ok
222
223 mov si, nosecsize_msg
224 call writemsg
225
226 params_ok:
227 ; Check for the sector size (should be 2048, but
228 ; some BIOSes apparently think we're 512-byte media)
229 ;
230 ; FIX: We need to check what the proper behaviour
231 ; is for getlinsec when the BIOS thinks the sector
232 ; size is 512!!! For that, we need such a BIOS, though...
233 %ifdef DEBUG_MESSAGES
234 mov si, secsize_msg
235 call writemsg
236 mov ax, [dp_secsize]
237 call writehex4
238 call crlf
239 %endif
240
241
242 ;
243 ; Clear Files structures
244 ;
245 mov di, Files
246 mov cx, (MAX_OPEN*open_file_t_size)/4
247 xor eax, eax
248 rep stosd
249
250 ;
251 ; Now, we need to sniff out the actual filesystem data structures.
252 ; mkisofs gave us a pointer to the primary volume descriptor
253 ; (which will be at 16 only for a single-session disk!); from the PVD
254 ; we should be able to find the rest of what we need to know.
255 ;
256 get_fs_structures:
257 mov eax, 16 ; Primary Volume Descriptor (sector 16)
258 mov bx, trackbuf
259 call getonesec
260
261 mov eax, [trackbuf+156+2]
262 mov [RootDir+dir_lba],eax
263 mov [CurDir+dir_lba],eax
264 %ifdef DEBUG_MESSAGES
265 mov si, rootloc_msg
266 call writemsg
267 call writehex8
268 call crlf
269 %endif
270
271 mov eax,[trackbuf+156+10]
272 mov [RootDir+dir_len],eax
273 mov [CurDir+dir_len],eax
274 %ifdef DEBUG_MESSAGES
275 mov si, rootlen_msg
276 call writemsg
277 call writehex8
278 call crlf
279 %endif
280 add eax,SECTORSIZE-1
281 shr eax,SECTORSIZE_LG2
282 mov [RootDir+dir_clust],eax
283 mov [CurDir+dir_clust],eax
284 %ifdef DEBUG_MESSAGES
285 mov si, rootsect_msg
286 call writemsg
287 call writehex8
288 call crlf
289 %endif
290
291 ; Look for the "X86" directory, and if found,
292 ; make it the current directory instead of the root
293 ; directory.
294 mov di,isolinux_dir
295 mov al,02h ; Search for a directory
296 call searchdir_iso
297 jnz .dir_found
298 mov si,no_dir_msg
299 call writemsg
300 jmp kaboom
301
302 .dir_found:
303 mov [CurDir+dir_len],eax
304 mov eax,[si+file_left]
305 mov [CurDir+dir_clust],eax
306 xor eax,eax ; Free this file pointer entry
307 xchg eax,[si+file_sector]
308 mov [CurDir+dir_lba],eax
309
310
311 mov di, isolinux_bin ; di points to Isolinux filename
312 call searchdir ; look for the file
313 jnz .isolinux_opened ; got the file
314 mov si, no_isolinux_msg ; si points to error message
315 call writemsg ; display the message
316 jmp kaboom ; fail boot
317
318 .isolinux_opened:
319 push si ; save file pointer
320
321 %ifdef DEBUG_MESSAGES
322 mov si, filelen_msg
323 call writemsg
324 call writehex8
325 call crlf
326 %endif
327
328 mov bx, 0x8000 ; bx = load address
329 pop si ; si = file pointer
330 mov cx, 0xFFFF ; load the whole file
331 call getfssec ; get the first sector
332 mov dl, [DriveNo] ; dl = boot drive
333 jmp 0:0x8000 ; jump into OSLoader
334
335
336
337 ;
338 ; searchdir:
339 ;
340 ; Open a file
341 ;
342 ; On entry:
343 ; DS:DI = filename
344 ; If successful:
345 ; ZF clear
346 ; SI = file pointer
347 ; DX:AX or EAX = file length in bytes
348 ; If unsuccessful
349 ; ZF set
350 ;
351
352 ;
353 ; searchdir_iso is a special entry point for ISOLINUX only. In addition
354 ; to the above, searchdir_iso passes a file flag mask in AL. This is useful
355 ; for searching for directories.
356 ;
357 alloc_failure:
358 xor ax,ax ; ZF <- 1
359 ret
360
361 searchdir:
362 xor al,al
363 searchdir_iso:
364 mov [ISOFlags],al
365 call allocate_file ; Temporary file structure for directory
366 jnz alloc_failure
367 push es
368 push ds
369 pop es ; ES = DS
370 mov si,CurDir
371 cmp byte [di],'\' ; If filename begins with slash
372 jne .not_rooted
373 inc di ; Skip leading slash
374 mov si,RootDir ; Reference root directory instead
375 .not_rooted:
376 mov eax,[si+dir_clust]
377 mov [bx+file_left],eax
378 mov eax,[si+dir_lba]
379 mov [bx+file_sector],eax
380 mov edx,[si+dir_len]
381
382 .look_for_slash:
383 mov ax,di
384 .scan:
385 mov cl,[di]
386 inc di
387 and cl,cl
388 jz .isfile
389 cmp cl,'\'
390 jne .scan
391 mov [di-1],byte 0 ; Terminate at directory name
392 mov cl,02h ; Search for directory
393 xchg cl,[ISOFlags]
394 push di
395 push cx
396 push word .resume ; Where to "return" to
397 push es
398 .isfile:
399 xchg ax,di
400
401 .getsome:
402 ; Get a chunk of the directory
403 mov si,trackbuf
404 pushad
405 xchg bx,si
406 mov cx,1 ; load one sector
407 call getfssec
408 popad
409
410 .compare:
411 movzx eax, byte [si] ; Length of directory entry
412 cmp al, 33
413 jb .next_sector
414 mov cl, [si+25]
415 xor cl, [ISOFlags]
416 test cl, byte 8Eh ; Unwanted file attributes!
417 jnz .not_file
418 pusha
419 movzx cx, byte [si+32] ; File identifier length
420 add si, byte 33 ; File identifier offset
421 call iso_compare_names
422 popa
423 je .success
424 .not_file:
425 sub edx, eax ; Decrease bytes left
426 jbe .failure
427 add si, ax ; Advance pointer
428
429 .check_overrun:
430 ; Did we finish the buffer?
431 cmp si, trackbuf+trackbufsize
432 jb .compare ; No, keep going
433
434 jmp short .getsome ; Get some more directory
435
436 .next_sector:
437 ; Advance to the beginning of next sector
438 lea ax, [si+SECTORSIZE-1]
439 and ax, ~(SECTORSIZE-1)
440 sub ax, si
441 jmp short .not_file ; We still need to do length checks
442
443 .failure:
444 %ifdef DEBUG_MESSAGES
445 mov si, findfail_msg
446 call writemsg
447 call crlf
448 %endif
449 xor eax, eax ; ZF = 1
450 mov [bx+file_sector], eax
451 pop es
452 ret
453
454 .success:
455 mov eax, [si+2] ; Location of extent
456 mov [bx+file_sector], eax
457 mov eax, [si+10] ; Data length
458 push eax
459 add eax, SECTORSIZE-1
460 shr eax, SECTORSIZE_LG2
461 mov [bx+file_left], eax
462 pop eax
463 mov edx, eax
464 shr edx, 16
465 and bx, bx ; ZF = 0
466 mov si, bx
467 pop es
468 ret
469
470 .resume:
471 ; We get here if we were only doing part of a lookup
472 ; This relies on the fact that .success returns bx == si
473 xchg edx, eax ; Directory length in edx
474 pop cx ; Old ISOFlags
475 pop di ; Next filename pointer
476
477 mov byte [di-1], '\' ; restore the backslash in the filename
478
479 mov [ISOFlags], cl ; Restore the flags
480 jz .failure ; Did we fail? If so fail for real!
481 jmp .look_for_slash ; Otherwise, next level
482
483 ;
484 ; allocate_file: Allocate a file structure
485 ;
486 ; If successful:
487 ; ZF set
488 ; BX = file pointer
489 ; In unsuccessful:
490 ; ZF clear
491 ;
492 allocate_file:
493 push cx
494 mov bx, Files
495 mov cx, MAX_OPEN
496 .check:
497 cmp dword [bx], byte 0
498 je .found
499 add bx, open_file_t_size ; ZF = 0
500 loop .check
501 ; ZF = 0 if we fell out of the loop
502 .found:
503 pop cx
504 ret
505
506 ;
507 ; iso_compare_names:
508 ; Compare the names DS:SI and DS:DI and report if they are
509 ; equal from an ISO 9660 perspective. SI is the name from
510 ; the filesystem; CX indicates its length, and ';' terminates.
511 ; DI is expected to end with a null.
512 ;
513 ; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment
514 ;
515 iso_compare_names:
516 ; First, terminate and canonicalize input filename
517 push di
518 mov di, ISOFileName
519 .canon_loop:
520 jcxz .canon_end
521 lodsb
522 dec cx
523 cmp al, ';'
524 je .canon_end
525 and al, al
526 je .canon_end
527 stosb
528 cmp di, ISOFileNameEnd-1 ; Guard against buffer overrun
529 jb .canon_loop
530 .canon_end:
531 cmp di, ISOFileName
532 jbe .canon_done
533 cmp byte [di-1], '.' ; Remove terminal dots
534 jne .canon_done
535 dec di
536 jmp short .canon_end
537 .canon_done:
538 mov [di], byte 0 ; Null-terminate string
539 pop di
540 mov si, ISOFileName
541 .compare:
542 lodsb
543 mov ah, [di]
544 inc di
545 and ax, ax
546 jz .success ; End of string for both
547 and al, al ; Is either one end of string?
548 jz .failure ; If so, failure
549 and ah, ah
550 jz .failure
551 or ax, 2020h ; Convert to lower case
552 cmp al, ah
553 je .compare
554 .failure:
555 and ax, ax ; ZF = 0 (at least one will be nonzero)
556 .success:
557 ret
558
559
560
561
562
563
564
565 ;
566 ; getfssec: Get multiple clusters from a file, given the file pointer.
567 ;
568 ; On entry:
569 ; ES:BX -> Buffer
570 ; SI -> File pointer
571 ; CX -> Cluster count; 0FFFFh = until end of file
572 ; On exit:
573 ; SI -> File pointer (or 0 on EOF)
574 ; CF = 1 -> Hit EOF
575 ;
576 getfssec:
577 cmp cx, [si+file_left]
578 jna .ok_size
579 mov cx, [si+file_left]
580
581 .ok_size:
582 mov bp, cx
583 push cx
584 push si
585 mov eax, [si+file_sector]
586 call getlinsec
587 xor ecx, ecx
588 pop si
589 pop cx
590
591 add [si+file_sector], ecx
592 sub [si+file_left], ecx
593 ja .not_eof ; CF = 0
594
595 xor ecx, ecx
596 mov [si+file_sector], ecx ; Mark as unused
597 xor si,si
598 stc
599
600 .not_eof:
601 ret
602
603
604
605 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
606 ; Try to scan the entire 80h-FFh from the end.
607 spec_query_failed:
608 mov si,spec_err_msg
609 call writemsg
610
611 mov dl, 0FFh
612 .test_loop:
613 pusha
614 mov ax, 4B01h
615 mov si, spec_packet
616 mov byte [si], 13 ; Size of buffer
617 int 13h
618 popa
619 jc .still_broken
620
621 mov si, maybe_msg
622 call writemsg
623 mov al, dl
624 call writehex2
625 call crlf
626
627 cmp byte [sp_drive], dl
628 jne .maybe_broken
629
630 ; Okay, good enough...
631 mov si, alright_msg
632 call writemsg
633 mov [DriveNo], dl
634 .found_drive:
635 jmp found_drive
636
637 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
638 ; but if this was the drive number originally passed in
639 ; DL then consider it "good enough"
640 .maybe_broken:
641 cmp byte [DriveNo], dl
642 je .found_drive
643
644 .still_broken: dec dx
645 cmp dl, 80h
646 jnb .test_loop
647
648 fatal_error:
649 mov si, nothing_msg
650 call writemsg
651
652 .norge:
653 jmp short .norge
654
655
656
657 ; Information message (DS:SI) output
658 ; Prefix with "isolinux: "
659 ;
660 writemsg:
661 push ax
662 push si
663 mov si, isolinux_str
664 call writestr
665 pop si
666 call writestr
667 pop ax
668 ret
669
670 ;
671 ; crlf: Print a newline
672 ;
673 crlf:
674 mov si, crlf_msg
675 ; Fall through
676
677 ;
678 ; writestr: write a null-terminated string to the console, saving
679 ; registers on entry.
680 ;
681 writestr:
682 pushfd
683 pushad
684 .top:
685 lodsb
686 and al, al
687 jz .end
688 call writechr
689 jmp short .top
690 .end:
691 popad
692 popfd
693 ret
694
695
696 ;
697 ; writehex[248]: Write a hex number in (AL, AX, EAX) to the console
698 ;
699 writehex2:
700 pushfd
701 pushad
702 shl eax, 24
703 mov cx, 2
704 jmp short writehex_common
705 writehex4:
706 pushfd
707 pushad
708 shl eax, 16
709 mov cx, 4
710 jmp short writehex_common
711 writehex8:
712 pushfd
713 pushad
714 mov cx, 8
715 writehex_common:
716 .loop:
717 rol eax, 4
718 push eax
719 and al, 0Fh
720 cmp al, 10
721 jae .high
722 .low:
723 add al, '0'
724 jmp short .ischar
725 .high:
726 add al, 'A'-10
727 .ischar:
728 call writechr
729 pop eax
730 loop .loop
731 popad
732 popfd
733 ret
734
735 ;
736 ; Write a character to the screen. There is a more "sophisticated"
737 ; version of this in the subsequent code, so we patch the pointer
738 ; when appropriate.
739 ;
740
741 writechr:
742 pushfd
743 pushad
744 mov ah, 0Eh
745 xor bx, bx
746 int 10h
747 popad
748 popfd
749 ret
750
751 ;
752 ; Get one sector. Convenience entry point.
753 ;
754 getonesec:
755 mov bp, 1
756 ; Fall through to getlinsec
757
758 ;
759 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
760 ;
761 ; Note that we can't always do this as a single request, because at least
762 ; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick
763 ; to 32 sectors (64K) per request.
764 ;
765 ; Input:
766 ; EAX - Linear sector number
767 ; ES:BX - Target buffer
768 ; BP - Sector count
769 ;
770 getlinsec:
771 mov si,dapa ; Load up the DAPA
772 mov [si+4],bx
773 mov bx,es
774 mov [si+6],bx
775 mov [si+8],eax
776 .loop:
777 push bp ; Sectors left
778 cmp bp,byte 32
779 jbe .bp_ok
780 mov bp,32
781 .bp_ok:
782 mov [si+2],bp
783 push si
784 mov dl,[DriveNo]
785 mov ah,42h ; Extended Read
786 call xint13
787 pop si
788 pop bp
789 movzx eax,word [si+2] ; Sectors we read
790 add [si+8],eax ; Advance sector pointer
791 sub bp,ax ; Sectors left
792 shl ax,SECTORSIZE_LG2-4 ; 2048-byte sectors -> segment
793 add [si+6],ax ; Advance buffer pointer
794 and bp,bp
795 jnz .loop
796 mov eax,[si+8] ; Next sector
797 ret
798
799 ; INT 13h with retry
800 xint13:
801 mov byte [RetryCount], 6
802 .try:
803 pushad
804 int 13h
805 jc .error
806 add sp, byte 8*4 ; Clean up stack
807 ret
808 .error:
809 mov [DiskError], ah ; Save error code
810 popad
811 dec byte [RetryCount]
812 jnz .try
813
814 .real_error:
815 mov si, diskerr_msg
816 call writemsg
817 mov al, [DiskError]
818 call writehex2
819 mov si, ondrive_str
820 call writestr
821 mov al, dl
822 call writehex2
823 call crlf
824 ; Fall through to kaboom
825
826 ;
827 ; kaboom: write a message and bail out. Wait for a user keypress,
828 ; then do a hard reboot.
829 ;
830 kaboom:
831 mov ax, cs
832 mov ds, ax
833 mov es, ax
834 mov fs, ax
835 mov gs, ax
836 sti
837 mov si, err_bootfailed
838 call writestr
839 call getchar
840 cli
841 mov word [BIOS_magic], 0 ; Cold reboot
842 jmp 0F000h:0FFF0h ; Reset vector address
843
844 getchar:
845 .again:
846 mov ah, 1 ; Poll keyboard
847 int 16h
848 jz .again
849 .kbd:
850 xor ax, ax ; Get keyboard input
851 int 16h
852 .func_key:
853 ret
854
855
856 ;
857 ; pollchar: check if we have an input character pending (ZF = 0)
858 ;
859 pollchar:
860 pushad
861 mov ah,1 ; Poll keyboard
862 int 16h
863 popad
864 ret
865
866
867
868 isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0
869 copyright_str db ' Copyright (C) 1994-2002 H. Peter Anvin', CR, LF, 0
870 presskey_msg db 'Press any key to boot from CD', 0
871 dot_msg db '.',0
872
873 %ifdef DEBUG_MESSAGES
874 startup_msg: db 'Starting up, DL = ', 0
875 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
876 secsize_msg: db 'Sector size appears to be ', 0
877 rootloc_msg: db 'Root directory location: ', 0
878 rootlen_msg: db 'Root directory length: ', 0
879 rootsect_msg: db 'Root directory length(sectors): ', 0
880 fileloc_msg: db 'FreeLdr.sys location: ', 0
881 filelen_msg: db 'FreeLdr.sys length: ', 0
882 filesect_msg: db 'FreeLdr.sys length(sectors): ', 0
883 findfail_msg: db 'Failed to find file!', 0
884 %endif
885
886 nosecsize_msg: db 'Failed to get sector size, assuming 0800', CR, LF, 0
887 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0
888 maybe_msg: db 'Found something at drive = ', 0
889 alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0
890 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF, 0
891 isolinux_str db 'IsoBoot: ', 0
892 crlf_msg db CR, LF, 0
893 diskerr_msg: db 'Disk error ', 0
894 ondrive_str: db ', drive ', 0
895 err_bootfailed db CR, LF, 'Boot failed: press a key to retry...'
896 isolinux_dir db '\REACTOS', 0
897 no_dir_msg db 'Could not find the REACTOS directory.', CR, LF, 0
898 isolinux_bin db 'FREELDR.SYS', 0
899 no_isolinux_msg db 'Could not find the file FREELDR.SYS.', CR, LF, 0
900
901 ;
902 ; El Torito spec packet
903 ;
904 align 8, db 0
905 spec_packet: db 13h ; Size of packet
906 sp_media: db 0 ; Media type
907 sp_drive: db 0 ; Drive number
908 sp_controller: db 0 ; Controller index
909 sp_lba: dd 0 ; LBA for emulated disk image
910 sp_devspec: dw 0 ; IDE/SCSI information
911 sp_buffer: dw 0 ; User-provided buffer
912 sp_loadseg: dw 0 ; Load segment
913 sp_sectors: dw 0 ; Sector count
914 sp_chs: db 0,0,0 ; Simulated CHS geometry
915 sp_dummy: db 0 ; Scratch, safe to overwrite
916
917 ;
918 ; EBIOS drive parameter packet
919 ;
920 align 8, db 0
921 drive_params: dw 30 ; Buffer size
922 dp_flags: dw 0 ; Information flags
923 dp_cyl: dd 0 ; Physical cylinders
924 dp_head: dd 0 ; Physical heads
925 dp_sec: dd 0 ; Physical sectors/track
926 dp_totalsec: dd 0,0 ; Total sectors
927 dp_secsize: dw 0 ; Bytes per sector
928 dp_dpte: dd 0 ; Device Parameter Table
929 dp_dpi_key: dw 0 ; 0BEDDh if rest valid
930 dp_dpi_len: db 0 ; DPI len
931 db 0
932 dw 0
933 dp_bus: times 4 db 0 ; Host bus type
934 dp_interface: times 8 db 0 ; Interface type
935 db_i_path: dd 0,0 ; Interface path
936 db_d_path: dd 0,0 ; Device path
937 db 0
938 db_dpi_csum: db 0 ; Checksum for DPI info
939
940 ;
941 ; EBIOS disk address packet
942 ;
943 align 8, db 0
944 dapa: dw 16 ; Packet size
945 .count: dw 0 ; Block count
946 .off: dw 0 ; Offset of buffer
947 .seg: dw 0 ; Segment of buffer
948 .lba: dd 0 ; LBA (LSW)
949 dd 0 ; LBA (MSW)
950
951 times 2048-($-$$) nop ; Pad to file offset 2048
952
953
954
955
956
957
958
959
960