]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/pbs.s
9bootfat: fat12 support
[plan9front.git] / sys / src / boot / pc / pbs.s
1 #include "x16.h"
2 #include "mem.h"
3
4 #define RELOC 0x7c00
5
6 TEXT _magic(SB), $0
7         BYTE $0xEB; BYTE $0x58;         /* jmp .+ 0x58  (_start0x5A) */
8         BYTE $0x90                      /* nop */
9 TEXT _version(SB), $0
10         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
11         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
12 TEXT _sectsize(SB), $0
13         BYTE $0x00; BYTE $0x00
14 TEXT _clustsize(SB), $0
15         BYTE $0x00
16 TEXT _nresrv(SB), $0
17         BYTE $0x00; BYTE $0x00
18 TEXT _nfats(SB), $0
19         BYTE $0x00
20 TEXT _rootsize(SB), $0
21         BYTE $0x00; BYTE $0x00
22 TEXT _volsize(SB), $0
23         BYTE $0x00; BYTE $0x00
24 TEXT _mediadesc(SB), $0
25         BYTE $0x00
26 TEXT _fatsize(SB), $0
27         BYTE $0x00; BYTE $0x00
28 TEXT _trksize(SB), $0
29         BYTE $0x00; BYTE $0x00
30 TEXT _nheads(SB), $0
31         BYTE $0x00; BYTE $0x00
32 TEXT _nhiddenlo(SB), $0
33         BYTE $0x00; BYTE $0x00
34 TEXT _nhiddenhi(SB), $0
35         BYTE $0x00; BYTE $0x00;
36 TEXT _bigvolsize(SB), $0
37         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
38 /* FAT32 structure, starting @0x24 */
39 TEXT _fatsz32lo(SB), $0
40         BYTE $0x00; BYTE $0x00
41 TEXT _fatsz32hi(SB), $0
42         BYTE $0x00; BYTE $0x00
43 TEXT _extflags(SB), $0
44         BYTE $0x00; BYTE $0x00
45 TEXT _fsver(SB), $0
46         BYTE $0x00; BYTE $0x00
47 TEXT _rootclust(SB), $0
48         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
49 TEXT _fsinfo(SB), $0
50         BYTE $0x00; BYTE $0x00
51 TEXT _bkboot(SB), $0
52         BYTE $0x00; BYTE $0x00
53 TEXT _reserved0(SB), $0
54         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
55         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
56         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
57 TEXT _driveno(SB), $0
58         BYTE $0x00
59 TEXT _reserved1(SB), $0
60         BYTE $0x00
61 TEXT _bootsig(SB), $0
62         BYTE $0x00
63 TEXT _volid(SB), $0
64         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
65 TEXT _label(SB), $0
66         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
67         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
68         BYTE $0x00; BYTE $0x00; BYTE $0x00
69 TEXT _type(SB), $0
70         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00;
71         BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x00
72
73 _start0x5A:
74         CLI
75         CLR(rAX)
76         MTSR(rAX, rSS)                  /* 0000 -> rSS */
77         MTSR(rAX, rDS)                  /* 0000 -> rDS, source segment */
78         MTSR(rAX, rES)
79
80         LWI(0x100, rCX)
81         LWI(RELOC, rSI)
82         MW(rSI, rSP)
83         LWI(_magic(SB), rDI)
84         CLD
85         REP; MOVSL                      /* MOV DS:[(E)SI] -> ES:[(E)DI] */
86
87         MW(rSP, rBP)
88
89         PUSHR(rCX)
90         PUSHI(start16(SB))
91         BYTE $0xCB                      /* FAR RET */
92
93 TEXT start16(SB), $0
94         STI
95
96         LWI(hello(SB), rSI)
97         CALL16(print16(SB))
98
99         STB(rDL, _driveno(SB))
100
101         CLR(rDX)
102         LW(_fatsize(SB), rAX)
103         CLR(rCX)
104         LB(_nfats(SB), rCL)
105         MUL(rCX)
106         OR(rAX, rAX)
107         JNE _fatszok    /* zero? it's FAT32 */
108
109         LW(_fatsz32hi(SB), rBX)
110         IMUL(rCX, rBX)
111         LW(_fatsz32lo(SB), rAX)
112         MUL(rCX)
113         ADD(rBX, rDX)
114
115 _fatszok:
116         LW(_nhiddenlo(SB), rCX)
117         ADD(rCX, rAX)
118         LW(_nhiddenhi(SB), rCX)
119         ADC(rCX, rDX)
120
121         CLR(rBX)
122         LW(_nresrv(SB), rCX)
123         ADD(rCX, rAX)
124         ADC(rDX, rBX)
125
126         SW(rAX, _volid(SB))     /* save for later use */
127         SW(rBX, _volid+2(SB))
128
129         PUSHR(rBP)
130         LW(_sectsize(SB), rCX)
131         SUB(rCX, rSP)
132         MW(rSP, rBP)
133         MW(rSP, rSI)
134
135 _nextsect:
136         CALL16(readsect16(SB))
137         LW(_sectsize(SB), rCX)
138         SHRI(5, rCX)
139
140 _nextdir:
141         PUSHR(rCX)
142         PUSHR(rSI)                      /* save for later if it matches */
143         LWI(bootname(SB), rDI)
144         LW(bootnamelen(SB), rCX)
145         CLD
146         REP
147         CMPSB
148         POPR(rSI)
149         POPR(rCX)
150         JEQ _found
151         ADDI(0x20, rSI) 
152         LOOP _nextdir
153         ADDI(1, rAX)
154         ADC(rCX, rBX)
155         JMP _nextsect
156
157 _found:
158         CLR(rBX)
159
160         LW(_rootsize(SB), rAX)          /* calculate and save Xrootsz */
161         LWI(0x20, rCX)
162         MUL(rCX)
163         LW(_sectsize(SB), rCX)
164         PUSHR(rCX)
165         DEC(rCX)
166         ADD(rCX, rAX)
167         ADC(rBX, rDX)
168         POPR(rCX)                       /* _sectsize(SB) */
169         DIV(rCX)
170         PUSHR(rAX)                      /* Xrootsz */
171
172         LXW(0x1a, xSI, rAX)             /* starting sector address */
173         DEC(rAX)                        /* that's just the way it is */
174         DEC(rAX)
175         LB(_clustsize(SB), rCL)
176         CLRB(rCH)
177         MUL(rCX)
178         LW(_volid(SB), rCX)             /* Xrootlo */
179         ADD(rCX, rAX)
180         LW(_volid+2(SB), rCX)           /* Xroothi */
181         ADC(rCX, rDX)
182         POPR(rCX)                       /* Xrootsz */
183         ADD(rCX, rAX)
184         ADC(rBX, rDX)
185
186         PUSHR(rAX)                      /* calculate how many sectors to read */
187         PUSHR(rDX)
188         LXW(0x1c, xSI, rAX)
189         LXW(0x1e, xSI, rDX)
190         LW(_sectsize(SB), rCX)
191         PUSHR(rCX)
192         DEC(rCX)
193         ADD(rCX, rAX)
194         ADC(rBX, rDX)
195         POPR(rCX)       /* _sectsize(SB) */
196         DIV(rCX)
197         MW(rAX, rCX)
198         POPR(rBX)
199         POPR(rAX)
200
201         LWI(RELOC, rSI)
202         PUSHR(rSI)      /* entry */
203
204 _loadnext:
205         CALL16(readsect16(SB))
206
207         LW(_sectsize(SB), rDX)
208         ADD(rDX, rSI)
209
210         CLR(rDX)
211         ADDI(1, rAX)
212         ADC(rDX, rBX)
213
214         LOOP _loadnext
215
216         LWI(ok(SB), rSI)
217         CALL16(print16(SB))
218
219         LB(_driveno(SB), rDL)
220         CLI
221         RET
222
223 TEXT print16(SB), $0
224         PUSHA
225         CLR(rBX)
226 _printnext:
227         LODSB
228         ORB(rAL, rAL)
229         JEQ _printret
230         LBI(0x0E, rAH)
231         BIOSCALL(0x10)
232         JMP _printnext
233 _printret:
234         POPA
235         RET
236
237 /*
238  * in:
239  *      AX:BX lba32,
240  *      0000:SI buffer
241  */
242 TEXT readsect16(SB), $0
243 _retry:
244         PUSHA
245         CLR(rDX)
246
247         PUSHR(rDX)              /* qword lba */
248         PUSHR(rDX)
249         PUSHR(rBX)
250         PUSHR(rAX)
251
252         PUSHR(rDX)              /* dword buffer */
253         PUSHR(rSI)
254
255         INC(rDX)
256         PUSHR(rDX)              /* word # of sectors */
257
258         PUSHI(0x0010)           /* byte reserved, byte packet size */
259
260         MW(rSP, rSI)
261         LB(_driveno(SB), rDL)
262         LWI(0x4200, rAX)
263         BIOSCALL(0x13)
264         JCC _readok
265         LWI((0x0E00|'!'), rAX)
266         BIOSCALL(0x10)
267         ADDI(0x10, rSP)
268         POPA
269         JMP _retry
270 _readok:
271         LWI((0x0E00|'.'), rAX)
272         BIOSCALL(0x10)
273         ADDI(0x10, rSP)
274         POPA
275         RET
276
277 TEXT bootnamelen(SB), $0
278         WORD $8
279 TEXT bootname(SB), $0
280         BYTE $'9'; BYTE $'B'; BYTE $'O'; BYTE $'O';
281         BYTE $'T'; BYTE $'F'; BYTE $'A'; BYTE $'T';
282         BYTE $0
283
284 TEXT hello(SB), $0
285         BYTE $'p'; BYTE $'b'; BYTE $'s'; BYTE $0
286 TEXT ok(SB), $0
287         BYTE $'o'; BYTE $'k'; BYTE $'\r'; BYTE $'\n';
288         BYTE $0