3 ; Copyright (c) 1998 Brian Palmer
22 MediaDescriptor db 0f0h
31 SerialNumber dd 00000000h
32 VolumeLabel db 'FreeLoader!'
33 FileSystem db 'FAT12 '
40 mov sp,7c00h ; Setup a stack
41 mov ax,cs ; Setup segment registers
42 mov ds,ax ; Make DS correct
43 mov es,ax ; Make ES correct
47 mov [BootDrive],dl ; Save the boot drive
48 xor ax,ax ; Zero out AX
50 ; Reset disk controller
53 jmp BadBoot ; Reset failed...
56 ; Now we must find our way to the first sector of the root directory
59 mov al,[NumberOfFats] ; Number of fats
60 mul WORD [SectorsPerFat] ; Times sectors per fat
61 add ax,WORD [HiddenSectors]
62 adc dx,WORD [HiddenSectors+2] ; Add the number of hidden sectors
63 add ax,[ReservedSectors] ; Add the number of reserved sectors
64 adc dx,cx ; Add carry bit
65 push ax ; Store it on the stack
66 push dx ; Save 32-bit logical start sector
68 push dx ; Save it for later use also
69 ; DX:AX now has the number of the starting sector of the root directory
71 ; Now calculate the size of the root directory
72 mov ax,0020h ; Size of dir entry
73 mul WORD [MaxRootEntries] ; Times the number of entries
74 mov bx,[BytesPerSector]
77 div bx ; Divided by the size of a sector
78 ; AX now has the number of root directory sectors
80 xchg ax,cx ; Now CX has number of sectors
82 pop ax ; Restore logical sector start
83 push cx ; Save for later use
84 mov bx,7c0h ; We will load the root directory
85 add bx,20h ; Right after the boot sector in memory
87 xor bx,bx ; We will load it to [0000:7e00h]
88 call ReadSectors ; Read the sectors
89 jnc Continue2 ; BadBoot on error
94 ; Now we have to find our way through the root directory to
95 ; The OSLOADER.SYS file
96 mov bx,[MaxRootEntries]; Search entire root directory
97 mov ax,7e0h ; We loaded at 07e0:0000
102 rep cmpsb ; Compare filenames
103 jz FoundFile ; If same we found it
109 mov ax,es ; We didn't find it in the previous dir entry
110 add ax,2 ; So lets move to the next one
111 mov es,ax ; And search again
115 rep cmpsb ; Compare filenames
116 jz FoundFile ; If same we found it
117 dec bx ; Keep searching till we run out of dir entries
118 jnz FindFile ; Last entry?
122 xor di,di ; ES:DI has dir entry
124 mov ax,WORD [es:di+1ah] ; Get start cluster
128 mov cl,BYTE [SectsPerCluster] ; Times sectors per cluster
130 pop cx ; Get number of sectors for root dir
133 pop cx ; Get logical start sector of
134 pop bx ; Root directory
135 add ax,bx ; Now we have DX:AX with the logical start
136 adc dx,cx ; Sector of OSLOADER.SYS
139 mov ax,WORD [es:di+1ch]
140 mov dx,WORD [es:di+1eh]
141 mov bx,[BytesPerSector]
145 div WORD [BytesPerSector]
146 xchg ax,cx ; Now CX has number of sectors of OSLOADER.SYS
151 xor bx,bx ; Load ROSLDR at 0000:8000h
152 call ReadSectors ; Load it
158 push ax ; We will do a far return to 0000:8000h
159 retf ; Transfer control to ROSLDR
163 ; Reads logical sectors into [ES:BX]
164 ; DX:AX has logical sector number to read
165 ; CX has number of sectors to read
166 ; CarryFlag set on error
174 div WORD [SectorsPerTrack]
176 div WORD [SectorsPerTrack] ; Divide logical by SectorsPerTrack
177 inc dx ; Sectors numbering starts at 1 not 0
179 div WORD [NumberOfHeads] ; Number of heads
180 mov dh,dl ; Head to DH, drive to DL
181 mov dl,[BootDrive] ; Drive number
182 mov ch,al ; Cylinder in CX
183 ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
184 ror ah,1 ; in CL shifted to bits 6 & 7
185 or cl,ah ; Or with sector number
187 int 13h ; DISK - READ SECTORS INTO MEMORY
188 ; AL = number of sectors to read, CH = track, CL = sector
189 ; DH = head, DL = drive, ES:BX -> buffer to fill
190 ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
195 inc ax ;Increment Sector to Read
206 ; Increment read buffer for next sector
207 loop ReadSectors ; Read next sector
215 ; Displays a bad boot message
218 mov si,msgDiskError ; Bad boot disk message
219 call PutChars ; Display it
220 mov si,msgAnyKey ; Press any key message
221 call PutChars ; Display it
225 ; Displays an error message
228 mov si,msgFreeLdr ; FreeLdr not found message
229 call PutChars ; Display it
230 mov si,msgAnyKey ; Press any key message
231 call PutChars ; Display it
235 int 16h ; Wait for a keypress
249 msgDiskError db 'Disk error',0dh,0ah,0
250 msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
251 msgAnyKey db 'Press any key to continue.',0dh,0ah,0
252 filename db 'FREELDR SYS'
254 times 510-($-$$) db 0 ; Pad to 510 bytes
255 dw 0aa55h ; BootSector signature