2 ; Loads the kernel and any required modules
8 ; Segment where we are loaded
13 ; Segment used for temporay storage
21 ; Offsets of work areas
26 END_DIR_BUFFER equ 0ffe0h
32 ; These are all on the stack
35 %define bytesPerSector [bp+0bh]
36 %define sectPerCluster [bp+0dh]
37 %define resSectors [bp+0eh]
38 %define nFats [bp+10h]
39 %define nRootDir [bp+11h]
40 %define nSectors [bp+13h]
42 %define sectPerFat [bp+16h]
43 %define sectPerTrack [bp+18h]
44 %define nHeads [bp+1ah]
45 %define nHidden [bp+1ch]
46 %define nHidden_hi [bp+1eh]
47 %define nSectorHuge [bp+20h]
48 %define drive [bp+24h]
49 %define extBoot [bp+26h]
50 %define volid [bp+27h]
51 %define vollabel [bp+2bh]
56 %define fat_start [bp-4] ; first FAT sector
57 %define fat_start_hi [bp-2]
58 %define root_dir_start [bp-8] ; first root directory sector
59 %define root_dir_start_hi [bp-6]
60 %define data_start [bp-12] ; first data sector
61 %define data_start_hi [bp-10]
79 ; Check here for shift pressed and if so display boot menu
100 mov dx,root_dir_start_hi
101 mov ax,root_dir_start
110 ; Look for a directory called boot
123 cmp di,END_DIR_BUFFER
146 ; Load the boot directory found above
157 %define file_length [di+01ch]
158 %define start_cluster [di+01ah]
160 cmp byte extBoot, 29h
162 cmp byte [bp+filesys+4], '6' ; check for FAT-16 system
178 ; readDisk: Reads a number of sectors into memory.
180 ; Call with: DX:AX = 32-bit DOS sector number
181 ; DI = number of sectors to read
182 ; ES:BX = destination buffer
183 ; ES must be 64k aligned (1000h, 2000h etc).
185 ; Returns: CF set on error
186 ; ES:BX points one byte after the last byte read.
195 ; translate sector number to BIOS parameters
199 ; abs = sector offset in track
200 ; + head * sectPerTrack offset in cylinder
201 ; + track * sectPerTrack * nHeads offset in platter
203 ; t1 = abs / sectPerTrack (ax has t1)
204 ; sector = abs mod sectPerTrack (cx has sector)
206 div word sectPerTrack
210 ; t1 = head + track * nHeads
212 ; track = t1 / nHeads (ax has track)
213 ; head = t1 mod nHeads (dl has head)
218 ; the following manipulations are necessary in order to
219 ; properly place parameters into registers.
220 ; ch = cylinder number low 8 bits
221 ; cl = 7-6: cylinder high two bits
223 mov dh, dl ; save head into dh for bios
224 ror ah, 1 ; move track high bits into
225 ror ah, 1 ; bits 7-6 (assumes top = 0)
226 xchg al, ah ; swap for later
227 mov dl, byte sectPerTrack
229 inc cl ; sector offset from 1
230 or cx, ax ; merge cylinder into sector
231 mov al, dl ; al has # of sectors left
233 ; Calculate how many sectors can be transfered in this read
234 ; due to dma boundary conditions.
237 mov si, di ; temp register save
238 ; this computes remaining bytes because of modulo 65536
239 ; nature of dma boundary condition
240 mov ax, bx ; get offset pointer
241 neg ax ; and convert to bytes
242 jz ax_min_1 ; started at seg:0, skip ahead
244 xor dx, dx ; convert to sectors
245 div word bytesPerSector
247 cmp ax, di ; check remainder vs. asked
248 jb ax_min_1 ; less, skip ahead
249 mov si, ax ; transfer only what we can
253 ; Check that request sectors do not exceed track boundary
256 mov ax, cx ; get the sector/cyl byte
257 and ax, 03fh ; and mask out sector
258 sub si, ax ; si has how many we can read
260 cmp si, di ; see if asked <= available
262 mov ax, si ; get what can be xfered
264 ax_min_2: mov si, RETRYCOUNT
273 xor ax, ax ; reset the drive
285 read_next_jmp: jmp short read_next
287 mov si, ax ; AX = SI = number of sectors read
288 mul word bytesPerSector ; AX = number of bytes read
289 add bx, ax ; add number of bytes read to BX
290 jnc no_incr_es ; if overflow...
293 add ah, 10h ; ...add 1000h to ES
297 pop dx ; DX:AX = last sector number
300 adc dx, 0 ; DX:AX = next sector to read
301 sub di, si ; if there is anything left to read,
302 jg read_next_jmp ; continue
310 ; Print string (DI = start)
334 loadmsg db "Starting ReactOS...",0xd,0xa,0
335 boot_dir_name db 'BOOT'
336 errormsg db "Files missing on boot disk",0
337 errormsg1 db "Disk read error",0
338 msg1 db "Found boot directory",0xd,0xa,0