]> wirehaze git hosting - BOS.git/blob - boot/BOS_boot.asm

wirehaze git hosting

Merge commit 'dba047e616f303ce818ba9ac7fb9f8a18a3717d3'
[BOS.git] / boot / BOS_boot.asm
1 ;------------------------------------------------------------;
2 ; BOS - FAT12 bootsector ;
3 ;------------------------------------------------------------;
4 ; - FAT12 compatible. ;
5 ; - Loads a binary file from the floppy. ;
6 ; ;
7 ;------------------------------------------------------------;
8
9 ; TODO:
10 ; as i moved some 16-bit stuff to the kernel, i now got
11 ; space to do proper testing (for data-area etc),
12 ; fix that...
13 ;
14 ; TODO2:
15 ; find out why this crap takes ages to load the kernel.. :S
16
17
18 ;
19 ; 16-bit mem map (seg:off)
20 ; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff
21 ; 0x0000:0x0500 -> 0x0000:0x2100 FAT12 rootdir
22 ; 0x0000:0x2100 -> 0x0000:0x3300 FAT for FAT12
23 ; 0x0000:0x3300 -> 0x0000:0x6c00 14,25kb free space
24 ; 0x0000:0x6c00 -> 0x0000:0x7400 IDT, 256 descriptors
25 ; 0x0000:0x7400 -> 0x0000:0x7c00 GDT, 256 descriptors
26 ; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector
27 ; 0x0000:0x7e00 <- 0x0000:0xffff ~32,5kb stack for boot
28 ; 0x1000:0x0000 -> 0x9000:0xffff 576kb kernel/free space
29 ; 0xa000:0x0000 -> ............. VGA mem etc.
30
31 use16
32 org 0x7C00
33
34 boot: jmp near start
35 nop
36
37 ;------------------------------------------;
38 ; Standard BIOS Parameter Block, "BPB". ;
39 ;------------------------------------------;
40 bpbOEM db 'BOS 0.04'
41 bpbSectSize dw 512
42 bpbClustSize db 1
43 bpbReservedSec dw 1
44 bpbFats db 2
45 bpbRootSize dw 224
46 bpbTotalSect dw 2880
47 bpbMedia db 240
48 bpbFatSize dw 9
49 bpbTrackSect dw 18
50 bpbHeads dw 2
51 bpbHiddenSect dd 0
52 bpbLargeSect dd 0
53 ;---------------------------------;
54 ; extended BPB for FAT12/FAT16 ;
55 ;---------------------------------;
56 bpbDriveNo db 0
57 bpbReserved db 0
58 bpbSignature db 41 ; 0 = nothing more. 41 = three more (below)..
59 bpbID dd 1
60 bpbVolumeLabel db 'BOOT FLOPPY'
61 bpbFileSystem db 'FAT12 '
62
63
64 ;----------------------------------------;
65 ; starting point of bootsector code ;
66 ;----------------------------------------;
67 start:
68 cli
69
70 xor ax, ax ; initialize all the necessary
71 mov ds, ax ; registers.
72 mov es, ax
73 mov ss, ax
74 mov sp, 0xFFFF ; Stack..
75
76 mov [bpbDriveNo], dl
77
78 sti
79
80
81 ;----------------------------------;
82 ; clear screen and print some ;
83 ;----------------------------------;
84 mov ax, 3 ; Set mode 0x03
85 int 0x10
86
87 mov bp, loading ; Print loading message.
88 mov ax, 0x1301
89 mov bx, 7
90 mov cx, 12
91 mov dx, 0x0102
92 int 0x10
93
94 mov bl, 2 ; Set cursor.
95 mov ah, 2
96 mov dx, 0x0201
97 int 0x10
98
99 mov ah, 9 ; Print 14 green dots.
100 mov al, '.'
101 mov cx, 14
102 int 0x10
103
104
105 ;---------------------------;
106 ; load FAT and root ;
107 ;---------------------------;
108 mov di, 0x0050 ; Load the root to
109 mov ax, 19 ; 0x0000:0x0500 (0x500/0x10)
110 mov cx, 14
111 call read_sectors
112
113 mov di, 0x0210 ; Load the fat to
114 mov ax, 1 ; 0x0000:0x2100
115 mov cx, 9
116 call read_sectors
117
118
119 ;------------------------;
120 ; search for the file ;
121 ;------------------------;
122 mov dx, [bpbRootSize]
123 mov bx, 0x0500
124 filesearch:
125 cld
126 mov si, filename
127 mov cx, 11
128 mov di, bx
129 repe cmpsb
130 je found
131 add bx, 32
132 dec dx
133 jz error
134 jmp filesearch
135
136
137 ;-----------------------------------;
138 ; variables & functions ;
139 ;-----------------------------------;
140 loading db 'Starting BOS'
141 filename db 'KERNEL SYS'
142 failure db 'Read error!'
143
144
145 ;-----------------------------------------------;
146 ; read a number of sectors (one at a time) ;
147 ;-----------------------------------------------;
148 ; in: ;
149 ; di = segment to save at ;
150 ; ax = sector to read ;
151 ; cx = number of sectors ;
152 ; out: ;
153 ; di = updated (added for next read) ;
154 ; ax = updated (added for next read) ;
155 ;-----------------------------------------------;
156 read_sectors:
157 pusha
158 mov bl, byte [bpbTrackSect] ; bl = number of sectors per track
159 div bl ; al = ax / bl
160 mov cl, ah ; cl = real sector number
161 add cl, 1
162
163 xor ah, ah ; del the rest of the div before
164 mov bl, byte [bpbHeads] ; bl = number of heads
165 div bl ; ah = rest of ( ax / bx ), al = ax / bx
166 mov ch, al ; ch = number of track
167 mov dh, ah ; dh = the head number
168
169 mov ax, cx ; save cx in ax
170 mov cx, 6 ; try it 6 times
171 .next_try:
172 push es
173 push cx
174 mov cx, ax ; restore cx
175 push cx
176
177 xor ax, ax
178 mov dl, [bpbDriveNo] ; reset drive
179 push dx
180 int 0x13
181 jc .failed
182
183 pop dx
184 pop cx
185 xor bx, bx
186 mov es, di
187 mov ax, 0x0201 ; function 2, 1 sector
188 int 0x13
189 jnc .ok ; if it was ok, check next..
190
191 .failed:
192 pop dx
193 pop ax
194
195 pop cx
196 pop es
197 loop .next_try ; else try once again if there is an error
198 jmp error ; if cx = 0 and the read operation failed, halt
199 .ok:
200 pop cx ; from the next_try loop
201 pop es
202 popa
203 add di, 32 ; add 32 (512/16) to segment
204 inc ax ; add sector counter
205 loop read_sectors
206 ret
207
208
209 ;----------------------------------------------------;
210 ; show a message and wait for a key before reboot ;
211 ;----------------------------------------------------;
212 error:
213 mov bp, failure
214 mov ax, 0x1301
215 mov bx, 4
216 mov cx, 11
217 mov dx, 0x0401
218 int 0x10
219
220 mov ah, 0
221 int 0x16
222 int 0x19
223
224
225 ;-----------------------------------;
226 ; the file is found, load it. ;
227 ;-----------------------------------;
228 found:
229 mov bp, [bx+26] ; bp=cluster number from directory entry
230 mov di, 0x1000 ; 1000 (segment)
231
232 .next_block:
233 xor cx, cx
234 mov cl, [bpbClustSize] ; reset sector count to 1 cluster
235 mov si, bp ; si=next should-be cluster for
236 ; contiguous reads
237 .next_contiguous:
238 mov ax, 3 ; 3
239 mul si ; multiply cluster number by 3
240 shr ax, 1 ; divide by two
241 mov bx, ax
242 mov ax, word [(0x2100+bx)] ; ax=FAT element with junk
243 jc .odd_cluster ; jump if the value was odd
244 and ax, 0x0FFF ; leave only lower 12 bits
245 jmp .got_cluster ; got it
246 .odd_cluster:
247 shr ax, 4 ; (leave only bits 4-15)
248
249 .got_cluster:
250 inc si ; si=current cluster+1
251 cmp ax, si ; next cluster=current cluster+1?
252 jne .force_read ; is it still contiguous?
253
254 add cl, [bpbClustSize] ; increase sector count by 1 cluster
255 adc ch, 0 ; add cf+0 to ch
256 jmp .next_contiguous
257
258 .force_read:
259 xchg bp, ax ; ax=bp (base cluster), bp=new cluster
260 dec ax ; decrease by 2 to get the actual...
261 dec ax ; ...cluster number
262
263 movzx dx, byte [bpbClustSize]
264 mul dx ; multiply by sectors per cluster
265 add ax, 33 ; add data-area location (33)
266 call read_sectors
267
268 cmp bp, 0x0FF8 ; is the new cluster EOF (FF8-FFF)?
269 jb .next_block ; if not, read next block
270
271 ;-----------------------;
272 ; the file is loaded ;
273 ;-----------------------;
274 quit:
275 jmp 0x1000:0x0000 ; jump to loaded file (64kb in mem)
276
277
278 ;-------------------------------------;
279 ; set the BOOT-signature at byte 510. ;
280 ;-------------------------------------;
281 rb boot+512-2-$
282 dw 0xAA55