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

wirehaze git hosting

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