]> git.lizzy.rs Git - plan9front.git/blob - sys/src/boot/pc/pbs.s
merge
[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         LW(_rootsize(SB), rAX)          /* calculate and save Xrootsz */
160         LWI(0x20, rCX)
161         MUL(rCX)
162         LW(_sectsize(SB), rCX)
163         DEC(rCX)
164         ADD(rCX, rAX)
165         ADC(rBX, rDX)
166         INC(rCX)
167         DIV(rCX)
168         PUSHR(rAX)                      /* Xrootsz */
169
170         CLR(rCX)
171         LXW(0x1a, xSI, rAX)             /* start cluster low */
172         LXW(0x14, xSI, rBX)             /* start cluster high */
173         SUBI(2, rAX)                    /* cluster -= 2 */
174         SBB(rCX, rBX)
175
176         LB(_clustsize(SB), rCL)         /* convert to sectors (AX:DX) */
177         IMUL(rCX, rBX)
178         MUL(rCX)
179         ADD(rBX, rDX)
180
181         LW(_volid(SB), rCX)             /* Xrootlo */
182         ADD(rCX, rAX)
183         LW(_volid+2(SB), rCX)           /* Xroothi */
184         ADC(rCX, rDX)
185
186         CLR(rBX)
187         POPR(rCX)                       /* Xrootsz */
188         ADD(rCX, rAX)
189         ADC(rBX, rDX)
190
191         PUSHR(rAX)                      /* calculate how many sectors to read (CX) */
192         PUSHR(rDX)
193         LXW(0x1c, xSI, rAX)
194         LXW(0x1e, xSI, rDX)
195         LW(_sectsize(SB), rCX)
196         DEC(rCX)
197         ADD(rCX, rAX)
198         ADC(rBX, rDX)
199         INC(rCX)
200         DIV(rCX)
201         MW(rAX, rCX)
202         POPR(rBX)
203         POPR(rAX)
204
205         LWI(RELOC, rSI)
206         PUSHR(rSI)      /* entry */
207
208 _loadnext:
209         CALL16(readsect16(SB))
210
211         LW(_sectsize(SB), rDX)
212         ADD(rDX, rSI)
213
214         CLR(rDX)
215         ADDI(1, rAX)
216         ADC(rDX, rBX)
217
218         LOOP _loadnext
219
220         LWI(ok(SB), rSI)
221         CALL16(print16(SB))
222
223         LB(_driveno(SB), rDL)
224         CLI
225         RET
226
227 TEXT print16(SB), $0
228         PUSHA
229         CLR(rBX)
230 _printnext:
231         LODSB
232         ORB(rAL, rAL)
233         JEQ _printret
234         LBI(0x0E, rAH)
235         BIOSCALL(0x10)
236         JMP _printnext
237 _printret:
238         POPA
239         RET
240
241 /*
242  * in:
243  *      AX:BX lba32,
244  *      0000:SI buffer
245  */
246 TEXT readsect16(SB), $0
247 _retry:
248         PUSHA
249         CLR(rDX)
250
251         PUSHR(rDX)              /* qword lba */
252         PUSHR(rDX)
253         PUSHR(rBX)
254         PUSHR(rAX)
255
256         PUSHR(rDX)              /* dword buffer */
257         PUSHR(rSI)
258
259         INC(rDX)
260         PUSHR(rDX)              /* word # of sectors */
261
262         PUSHI(0x0010)           /* byte reserved, byte packet size */
263
264         MW(rSP, rSI)
265         LB(_driveno(SB), rDL)
266         LWI(0x4200, rAX)
267         BIOSCALL(0x13)
268         JCC _readok
269         LWI((0x0E00|'!'), rAX)
270         BIOSCALL(0x10)
271         ADDI(0x10, rSP)
272         POPA
273         JMP _retry
274 _readok:
275         LWI((0x0E00|'.'), rAX)
276         BIOSCALL(0x10)
277         ADDI(0x10, rSP)
278         POPA
279         RET
280
281 TEXT bootnamelen(SB), $0
282         WORD $8
283 TEXT bootname(SB), $0
284         BYTE $'9'; BYTE $'B'; BYTE $'O'; BYTE $'O';
285         BYTE $'T'; BYTE $'F'; BYTE $'A'; BYTE $'T';
286         BYTE $0
287
288 TEXT hello(SB), $0
289         BYTE $'p'; BYTE $'b'; BYTE $'s'; BYTE $0
290 TEXT ok(SB), $0
291         BYTE $'o'; BYTE $'k'; BYTE $'\r'; BYTE $'\n';
292         BYTE $0