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

wirehaze git hosting

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