Rev 7215 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7215 | Rev 9942 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | ; FAT12 boot sector for Kolibri OS |
8 | ; FAT12 boot sector for Kolibri OS |
9 | ; |
9 | ; |
10 | ; Copyright (C) Alex Nogueira Teixeira |
10 | ; Copyright (C) Alex Nogueira Teixeira |
11 | ; Copyright (C) Diamond |
11 | ; Copyright (C) Diamond |
12 | ; Copyright (C) Dmitry Kartashov aka shurf |
12 | ; Copyright (C) Dmitry Kartashov aka shurf |
13 | ; |
13 | ; |
14 | ; Distributed under GPL, see file COPYING for details |
14 | ; Distributed under GPL, see file COPYING for details |
15 | ; |
15 | ; |
16 | ; Version 1.0 |
16 | ; Version 1.0 |
17 | 17 | ||
18 | include "lang.inc" |
18 | include "lang.inc" |
19 | 19 | ||
20 | lf = 0ah |
20 | lf = 0ah |
21 | cr = 0dh |
21 | cr = 0dh |
22 | 22 | ||
23 | pos_read_tmp = 0700h ;position for temporary read |
23 | pos_read_tmp = 0700h ;position for temporary read |
24 | boot_program = 07c00h ;position for boot code |
24 | boot_program = 07c00h ;position for boot code |
25 | seg_read_kernel = 01000h ;segment to kernel read |
25 | seg_read_kernel = 01000h ;segment to kernel read |
26 | 26 | ||
27 | jmp start_program |
27 | jmp start_program |
28 | nop |
28 | nop |
29 | 29 | ||
30 | ; Boot Sector and BPB Structure |
30 | ; Boot Sector and BPB Structure |
31 | include 'floppy1440.inc' |
31 | include 'floppy1440.inc' |
32 | ;include 'floppy2880.inc' |
32 | ;include 'floppy2880.inc' |
33 | ;include 'floppy1680.inc' |
33 | ;include 'floppy1680.inc' |
34 | ;include 'floppy1743.inc' |
34 | ;include 'floppy1743.inc' |
35 | 35 | ||
36 | start_program: |
36 | start_program: |
37 | ; |
37 | ; |
38 | cld ;clear direction flag for Phoenix BIOS, see next "lodsb" |
38 | cld ;clear direction flag for Phoenix BIOS, see next "lodsb" |
39 | xor ax, ax |
39 | xor ax, ax |
40 | cli |
40 | cli |
41 | mov ss, ax |
41 | mov ss, ax |
42 | mov sp, boot_program |
42 | mov sp, boot_program |
43 | sti |
43 | sti |
44 | ; <\Efremenkov S.V.> |
44 | ; <\Efremenkov S.V.> |
45 | push ss |
45 | push ss |
46 | pop ds |
46 | pop ds |
47 | 47 | ||
48 | ; print loading string |
48 | ; print loading string |
49 | mov si, loading+boot_program |
49 | mov si, loading+boot_program |
50 | loop_loading: |
50 | loop_loading: |
51 | lodsb |
51 | lodsb |
52 | or al, al |
52 | or al, al |
53 | jz read_root_directory |
53 | jz read_root_directory |
54 | mov ah, 0eh |
54 | mov ah, 0eh |
55 | mov bx, 7 |
55 | mov bx, 7 |
56 | int 10h |
56 | int 10h |
57 | jmp loop_loading |
57 | jmp loop_loading |
58 | 58 | ||
59 | read_root_directory: |
59 | read_root_directory: |
60 | push ss |
60 | push ss |
61 | pop es |
61 | pop es |
62 | 62 | ||
63 | ; calculate some disk parameters |
63 | ; calculate some disk parameters |
64 | ; - beginning sector of RootDir |
64 | ; - beginning sector of RootDir |
65 | mov ax, word [BPB_FATSz16+boot_program] |
65 | mov ax, word [BPB_FATSz16+boot_program] |
66 | xor cx, cx |
66 | xor cx, cx |
67 | mov cl, byte [BPB_NumFATs+boot_program] |
67 | mov cl, byte [BPB_NumFATs+boot_program] |
68 | mul cx |
68 | mul cx |
69 | add ax, word [BPB_RsvdSecCnt+boot_program] |
69 | add ax, word [BPB_RsvdSecCnt+boot_program] |
70 | mov word [FirstRootDirSecNum+boot_program], ax ; 19 |
70 | mov word [FirstRootDirSecNum+boot_program], ax ; 19 |
71 | mov si, ax |
71 | mov si, ax |
72 | 72 | ||
73 | ; - count of sectors in RootDir |
73 | ; - count of sectors in RootDir |
74 | mov bx, word [BPB_BytsPerSec+boot_program] |
74 | mov bx, word [BPB_BytsPerSec+boot_program] |
75 | mov cl, 5 ; divide ax by 32 |
75 | mov cl, 5 ; divide ax by 32 |
76 | shr bx, cl ; bx = directory entries per sector |
76 | shr bx, cl ; bx = directory entries per sector |
77 | mov ax, word [BPB_RootEntCnt+boot_program] |
77 | mov ax, word [BPB_RootEntCnt+boot_program] |
78 | xor dx, dx |
78 | xor dx, dx |
79 | div bx |
79 | div bx |
80 | mov word [RootDirSecs+boot_program], ax ; 14 |
80 | mov word [RootDirSecs+boot_program], ax ; 14 |
81 | 81 | ||
82 | ; - data start |
82 | ; - data start |
83 | add si, ax ; add beginning sector of RootDir and count sectors in RootDir |
83 | add si, ax ; add beginning sector of RootDir and count sectors in RootDir |
84 | mov word [data_start+boot_program], si ; 33 |
84 | mov word [data_start+boot_program], si ; 33 |
85 | ; reading root directory |
85 | ; reading root directory |
86 | ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! |
86 | ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! |
87 | mov ah, 2 ; read |
87 | mov ah, 2 ; read |
88 | push ax |
88 | push ax |
89 | 89 | ||
90 | mov ax, word [FirstRootDirSecNum+boot_program] |
90 | mov ax, word [FirstRootDirSecNum+boot_program] |
91 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
91 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
92 | pop ax |
92 | pop ax |
93 | mov bx, pos_read_tmp ; es:bx read buffer |
93 | mov bx, pos_read_tmp ; es:bx read buffer |
94 | call read_sector |
94 | call read_sector |
95 | 95 | ||
96 | mov si, bx ; read buffer address: es:si |
96 | mov si, bx ; read buffer address: es:si |
97 | mov ax, [RootDirSecs+boot_program] |
97 | mov ax, [RootDirSecs+boot_program] |
98 | mul word [BPB_BytsPerSec+boot_program] |
98 | mul word [BPB_BytsPerSec+boot_program] |
99 | add ax, si ; AX = end of root dir. in buffer pos_read_tmp |
99 | add ax, si ; AX = end of root dir. in buffer pos_read_tmp |
100 | 100 | ||
101 | ; find kernel file in root directory |
101 | ; find kernel file in root directory |
102 | loop_find_dir_entry: |
102 | loop_find_dir_entry: |
103 | push si |
103 | push si |
104 | mov cx, 11 |
104 | mov cx, 11 |
105 | mov di, kernel_name+boot_program |
105 | mov di, kernel_name+boot_program |
106 | rep cmpsb ; compare es:si and es:di, cx bytes long |
106 | rep cmpsb ; compare es:si and es:di, cx bytes long |
107 | pop si |
107 | pop si |
108 | je found_kernel_file |
108 | je found_kernel_file |
109 | add si, 32 ; next dir. entry |
109 | add si, 32 ; next dir. entry |
110 | cmp si, ax ; end of directory |
110 | cmp si, ax ; end of directory |
111 | jb loop_find_dir_entry |
111 | jb loop_find_dir_entry |
112 | 112 | ||
113 | file_error_message: |
113 | file_error_message: |
114 | mov si, error_message+boot_program |
114 | mov si, error_message+boot_program |
115 | 115 | ||
116 | loop_error_message: |
116 | loop_error_message: |
117 | lodsb |
117 | lodsb |
118 | or al, al |
118 | or al, al |
119 | jz freeze_pc |
119 | jz freeze_pc |
120 | mov ah, 0eh |
120 | mov ah, 0eh |
121 | mov bx, 7 |
121 | mov bx, 7 |
122 | int 10h |
122 | int 10h |
123 | jmp loop_error_message |
123 | jmp loop_error_message |
124 | 124 | ||
125 | freeze_pc: |
125 | freeze_pc: |
126 | jmp $ ; endless loop |
126 | jmp $ ; endless loop |
127 | 127 | ||
128 | ; === KERNEL FOUND. LOADING... === |
128 | ; === KERNEL FOUND. LOADING... === |
129 | 129 | ||
130 | found_kernel_file: |
130 | found_kernel_file: |
131 | mov bp, [si+01ah] ; first cluster of kernel file |
131 | mov bp, [si+01ah] ; first cluster of kernel file |
132 | ; |
- | |
133 | mov [cluster1st+boot_program], bp ; starting cluster of kernel file |
132 | mov [cluster1st+boot_program], bp ; starting cluster of kernel file |
134 | ; <\diamond> |
- | |
135 | 133 | ||
136 | ; reading first FAT table |
134 | ; reading first FAT table |
137 | mov ax, word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number |
135 | mov ax, word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number |
138 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
136 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
139 | mov bx, pos_read_tmp ; es:bx read position |
137 | mov bx, pos_read_tmp ; es:bx read position |
140 | mov ah, 2 ; ah=2 (read) |
138 | mov ah, 2 ; ah=2 (read) |
141 | mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) |
139 | mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) |
142 | call read_sector |
140 | call read_sector |
143 | jc file_error_message ; read error |
141 | jc file_error_message ; read error |
144 | 142 | ||
145 | mov ax, seg_read_kernel |
143 | mov ax, seg_read_kernel |
146 | mov es, ax |
144 | mov es, ax |
147 | xor bx, bx ; es:bx = 1000h:0000h |
145 | xor bx, bx ; es:bx = 1000h:0000h |
148 | 146 | ||
149 | 147 | ||
150 | ; reading kernel file |
148 | ; reading kernel file |
151 | loop_obtains_kernel_data: |
149 | loop_obtains_kernel_data: |
152 | ; read one cluster of file |
150 | ; read one cluster of file |
153 | call obtain_cluster |
151 | call obtain_cluster |
154 | jc file_error_message ; read error |
152 | jc file_error_message ; read error |
155 | 153 | ||
156 | ; add one cluster length to segment:offset |
154 | ; add one cluster length to segment:offset |
157 | push bx |
155 | push bx |
158 | mov bx, es |
156 | mov bx, es |
159 | mov ax, word [BPB_BytsPerSec+boot_program] ;\ |
157 | mov ax, word [BPB_BytsPerSec+boot_program] ;\ |
160 | movsx cx, byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! |
158 | movsx cx, byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! |
161 | mul cx ; | out this from loop !!! |
159 | mul cx ; | out this from loop !!! |
162 | shr ax, 4 ;/ |
160 | shr ax, 4 ;/ |
163 | add bx, ax |
161 | add bx, ax |
164 | mov es, bx |
162 | mov es, bx |
165 | pop bx |
163 | pop bx |
166 | 164 | ||
167 | mov di, bp |
165 | mov di, bp |
168 | shr di, 1 |
166 | shr di, 1 |
169 | pushf |
167 | pushf |
170 | add di, bp ; di = bp * 1.5 |
168 | add di, bp ; di = bp * 1.5 |
171 | add di, pos_read_tmp |
169 | add di, pos_read_tmp |
172 | mov ax, [di] ; read next entry from FAT-chain |
170 | mov ax, [di] ; read next entry from FAT-chain |
173 | popf |
171 | popf |
174 | jc move_4_right |
172 | jc move_4_right |
175 | and ax, 0fffh |
173 | and ax, 0fffh |
176 | jmp verify_end_sector |
174 | jmp verify_end_sector |
177 | move_4_right: |
175 | move_4_right: |
178 | mov cl, 4 |
176 | mov cl, 4 |
179 | shr ax, cl |
177 | shr ax, cl |
180 | verify_end_sector: |
178 | verify_end_sector: |
181 | cmp ax, 0ff8h ; last cluster |
179 | cmp ax, 0ff8h ; last cluster |
182 | jae execute_kernel |
180 | jae execute_kernel |
183 | mov bp, ax |
181 | mov bp, ax |
184 | jmp loop_obtains_kernel_data |
182 | jmp loop_obtains_kernel_data |
185 | 183 | ||
186 | execute_kernel: |
184 | execute_kernel: |
187 | ; |
- | |
188 | mov ax, 'KL' |
185 | mov ax, 'KL' |
189 | push 0 |
186 | push 0 |
190 | pop ds |
187 | pop ds |
191 | mov si, loader_block+boot_program |
188 | mov si, loader_block+boot_program |
192 | ; |
- | |
193 | push word seg_read_kernel |
189 | push word seg_read_kernel |
194 | push word 0 |
190 | push word 0 |
195 | retf ; jmp far 1000:0000 |
191 | retf ; jmp far 1000:0000 |
196 | 192 | ||
197 | 193 | ||
198 | ;------------------------------------------ |
194 | ;------------------------------------------ |
199 | ; loading cluster from file to es:bx |
195 | ; loading cluster from file to es:bx |
200 | obtain_cluster: |
196 | obtain_cluster: |
201 | ; bp - cluster number to read |
197 | ; bp - cluster number to read |
202 | ; carry = 0 -> read OK |
198 | ; carry = 0 -> read OK |
203 | ; carry = 1 -> read ERROR |
199 | ; carry = 1 -> read ERROR |
204 | 200 | ||
205 | ; print one dot |
201 | ; print one dot |
206 | push bx |
202 | push bx |
207 | mov ax, 0e2eh ; ah=0eh (teletype), al='.' |
203 | mov ax, 0e2eh ; ah=0eh (teletype), al='.' |
208 | xor bh, bh |
204 | xor bh, bh |
209 | int 10h |
205 | int 10h |
210 | pop bx |
206 | pop bx |
211 | 207 | ||
212 | writesec: |
208 | writesec: |
213 | ; convert cluster number to sector number |
209 | ; convert cluster number to sector number |
214 | mov ax, bp ; data cluster to read |
210 | mov ax, bp ; data cluster to read |
215 | sub ax, 2 |
211 | sub ax, 2 |
216 | xor dx, dx |
212 | xor dx, dx |
217 | mov dl, byte [BPB_SecPerClus+boot_program] |
213 | mov dl, byte [BPB_SecPerClus+boot_program] |
218 | mul dx |
214 | mul dx |
219 | add ax, word [data_start+boot_program] |
215 | add ax, word [data_start+boot_program] |
220 | 216 | ||
221 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
217 | call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) |
222 | patchhere: |
218 | patchhere: |
223 | mov ah, 2 ; ah=2 (read) |
219 | mov ah, 2 ; ah=2 (read) |
224 | mov al, byte [BPB_SecPerClus+boot_program] ; al=(one cluster) |
220 | mov al, byte [BPB_SecPerClus+boot_program] ; al=(one cluster) |
225 | call read_sector |
221 | call read_sector |
226 | retn |
222 | retn |
227 | ;------------------------------------------ |
223 | ;------------------------------------------ |
228 | 224 | ||
229 | ;------------------------------------------ |
225 | ;------------------------------------------ |
230 | ; read sector from disk |
226 | ; read sector from disk |
231 | read_sector: |
227 | read_sector: |
232 | push bp |
228 | push bp |
233 | mov bp, 20 ; try 20 times |
229 | mov bp, 20 ; try 20 times |
234 | newread: |
230 | newread: |
235 | dec bp |
231 | dec bp |
- | 232 | jnz .next |
|
- | 233 | cmp ah, 02h ; if read sectors |
|
236 | jz file_error_message |
234 | jz file_error_message |
- | 235 | mov byte[write_err+boot_program], 1 ; if write sectors |
|
- | 236 | jmp .ret |
|
- | 237 | .next: |
|
237 | push ax bx cx dx |
238 | push ax bx cx dx |
238 | int 13h |
239 | int 13h |
239 | pop dx cx bx ax |
240 | pop dx cx bx ax |
240 | jc newread |
241 | jc newread |
- | 242 | .ret: |
|
241 | pop bp |
243 | pop bp |
242 | retn |
244 | retn |
- | 245 | ||
243 | ;------------------------------------------ |
246 | ;------------------------------------------ |
244 | ; convert abs. sector number (AX) to BIOS T:H:S |
247 | ; convert abs. sector number (AX) to BIOS T:H:S |
245 | ; sector number = (abs.sector%BPB_SecPerTrk)+1 |
248 | ; sector number = (abs.sector%BPB_SecPerTrk)+1 |
246 | ; pre.track number = (abs.sector/BPB_SecPerTrk) |
249 | ; pre.track number = (abs.sector/BPB_SecPerTrk) |
247 | ; head number = pre.track number%BPB_NumHeads |
250 | ; head number = pre.track number%BPB_NumHeads |
248 | ; track number = pre.track number/BPB_NumHeads |
251 | ; track number = pre.track number/BPB_NumHeads |
249 | ; Return: cl - sector number |
252 | ; Return: cl - sector number |
250 | ; ch - track number |
253 | ; ch - track number |
251 | ; dl - drive number (0 = a:) |
254 | ; dl - drive number (0 = a:) |
252 | ; dh - head number |
255 | ; dh - head number |
253 | conv_abs_to_THS: |
256 | conv_abs_to_THS: |
254 | push bx |
257 | push bx |
255 | mov bx, word [BPB_SecPerTrk+boot_program] |
258 | mov bx, word [BPB_SecPerTrk+boot_program] |
256 | xor dx, dx |
259 | xor dx, dx |
257 | div bx |
260 | div bx |
258 | inc dx |
261 | inc dx |
259 | mov cl, dl ; cl = sector number |
262 | mov cl, dl ; cl = sector number |
260 | mov bx, word [BPB_NumHeads+boot_program] |
263 | mov bx, word [BPB_NumHeads+boot_program] |
261 | xor dx, dx |
264 | xor dx, dx |
262 | div bx |
265 | div bx |
263 | ; !!!!!!! ax = track number, dx = head number |
266 | ; !!!!!!! ax = track number, dx = head number |
264 | mov ch, al ; ch=track number |
267 | mov ch, al ; ch=track number |
265 | xchg dh, dl ; dh=head number |
268 | xchg dh, dl ; dh=head number |
266 | mov dl, 0 ; dl=0 (drive 0 (a:)) |
269 | mov dl, 0 ; dl=0 (drive 0 (a:)) |
267 | pop bx |
270 | pop bx |
268 | retn |
271 | retn |
269 | ;------------------------------------------ |
272 | ;------------------------------------------ |
270 | 273 | ||
271 | if lang eq sp |
274 | if lang eq sp |
272 | loading db cr,lf,'Iniciando el sistema ',00h |
275 | loading db cr,lf,'Iniciando el sistema ',00h |
273 | else |
276 | else |
274 | loading db cr,lf,'Starting system ',00h |
277 | loading db cr,lf,'Starting system ',00h |
275 | end if |
278 | end if |
276 | error_message db 13,10 |
279 | error_message db 13,10 |
277 | kernel_name db 'KERNEL MNT ?',cr,lf,00h |
280 | kernel_name db 'KERNEL MNT ?',cr,lf,00h |
278 | FirstRootDirSecNum dw ? |
281 | FirstRootDirSecNum dw ? |
279 | RootDirSecs dw ? |
282 | RootDirSecs dw ? |
280 | data_start dw ? |
283 | data_start dw ? |
281 | - | ||
282 | ; |
284 | |
283 | write1st: |
285 | write1st: |
284 | push cs |
286 | push cs |
285 | pop ds |
287 | pop ds |
286 | mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 |
288 | mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 |
287 | mov bp, [cluster1st+boot_program] |
289 | mov bp, [cluster1st+boot_program] |
288 | push 1000h |
290 | push 1000h |
289 | pop es |
291 | pop es |
290 | xor bx, bx |
292 | xor bx, bx |
291 | call writesec |
293 | call writesec |
292 | mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 |
294 | mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 |
293 | retf |
295 | retf |
294 | cluster1st dw ? |
296 | cluster1st dw ? |
295 | loader_block: |
297 | loader_block: |
296 | db 1 |
298 | db 1 ; +0 |
297 | dw 0 |
299 | dw 0 ; +1 |
298 | dw write1st+boot_program |
300 | dw write1st+boot_program ; +3 |
299 | dw 0 |
301 | dw 0 ; +5 |
300 | ; <\diamond> |
302 | write_err: db 0 ; +7 |
301 | 303 | ||
302 | times 0x1fe-$ db 00h |
304 | times 0x1fe-$ db 00h |
303 | 305 | ||
304 | db 55h,0aah ;boot signature\diamond>\diamond>\Efremenkov> |
306 | db 55h,0aah ;boot signature\Efremenkov> |