rev |
line source |
pascal@15188
|
1 SYSSEG = 0x1000
|
pascal@15188
|
2 INITSEG = 0x9000
|
pascal@15188
|
3 SETUPSEG = 0x9020
|
pascal@15188
|
4
|
pascal@15188
|
5 setup_sects = 497
|
pascal@15188
|
6 syssize = 500
|
pascal@15188
|
7
|
pascal@15188
|
8 .text
|
pascal@15188
|
9 .code16
|
pascal@15188
|
10 .org 0
|
pascal@15188
|
11 .globl _start
|
pascal@15188
|
12 _start:
|
pascal@15188
|
13
|
pascal@15188
|
14 #define CODESZ 512
|
pascal@15188
|
15
|
pascal@15188
|
16 /* some extra features */
|
pascal@15188
|
17 #define EXE_SUPPORT real mode dos .exe file support
|
pascal@15188
|
18 #define CMDLINE 0x9E00
|
pascal@15188
|
19 #define HELP store help message for /? argument
|
pascal@15188
|
20 #define CHECK_REALMODE does not support vm86
|
pascal@15188
|
21
|
pascal@15188
|
22 /* some contraints to reduce the size */
|
pascal@15188
|
23 //#define FLOPPY_1440K_ONLY 1.44M floppies support only
|
pascal@15188
|
24 #define NO_CURSOR_DEFINITION
|
pascal@15188
|
25
|
pascal@15188
|
26 #ifdef EXE_SUPPORT
|
pascal@15188
|
27 #define EXEADRS(x) x+0xE0
|
pascal@15188
|
28 stacktop = 0x9E00 # in 0x8000 .. 0xA000
|
pascal@15188
|
29 decw %bp // Magic number: MZ
|
pascal@15188
|
30 popw %dx
|
pascal@15188
|
31 jmp start // Bytes on last page of file
|
pascal@15188
|
32 .word (CODESZ+511)/512 // Pages in file
|
pascal@15188
|
33 .word 0 // Relocations
|
pascal@15188
|
34 .word (end_header-_start)/16 // Size of header in paragraphs
|
pascal@15188
|
35 .word 4096 // Minimum extra paragraphs needed
|
pascal@15188
|
36 .word -1 // Maximum extra paragraphs needed
|
pascal@15188
|
37 .word (CODESZ+15)/16 // Initial (relative) SS value
|
pascal@15188
|
38 .word stacktop // Initial SP value
|
pascal@15188
|
39 .word 0 // Checksum
|
pascal@15188
|
40 .word EXEADRS(comstart) // Initial IP value
|
pascal@15188
|
41 .word 0xFFF0 // Initial (relative) CS value
|
pascal@15188
|
42 // .word 0x001C // File address of relocation table
|
pascal@15188
|
43 // .word 0,0,0 // Overlay number
|
pascal@15188
|
44 .ascii "(SliTaz)"
|
pascal@15188
|
45 end_header:
|
pascal@15188
|
46 comstart:
|
pascal@15470
|
47 cld # assume nothing
|
pascal@15188
|
48 #ifdef CMDLINE
|
pascal@15470
|
49 movw $stacktop, %di
|
pascal@15471
|
50 #else
|
pascal@15188
|
51 #undef HELP
|
pascal@15188
|
52 #endif
|
pascal@15188
|
53 pushw $INITSEG
|
pascal@15188
|
54 popw %es
|
pascal@15188
|
55 #ifdef CMDLINE
|
pascal@15188
|
56 movw $0x80, %si
|
pascal@15188
|
57 lodsb
|
pascal@15188
|
58 cbw
|
pascal@15188
|
59 xchgw %ax, %cx
|
pascal@15188
|
60 jcxz nocmdline
|
pascal@15470
|
61 movw $0xA33F, 0x7F(%si)
|
pascal@15188
|
62 skipspace:
|
pascal@15188
|
63 lodsb
|
pascal@15188
|
64 cmpb $0x20, %al
|
pascal@15188
|
65 je skipspace
|
pascal@15188
|
66 decw %si
|
pascal@15188
|
67 rep
|
pascal@15188
|
68 movsb
|
pascal@15469
|
69 # if defined(HELP) || defined(CHECK_REALMODE)
|
pascal@15469
|
70 pushw %cx // dos exit (int $0x20)
|
pascal@15469
|
71 # endif
|
pascal@15188
|
72 # ifdef HELP
|
pascal@15188
|
73 # define PUTS
|
pascal@15188
|
74 movw $EXEADRS(helpmsg), %si
|
pascal@15188
|
75 cmpb $'/', %al
|
pascal@15476
|
76 # ifdef CHECK_REALMODE
|
pascal@15476
|
77 je jeputs
|
pascal@15476
|
78 # else
|
pascal@15188
|
79 je puts
|
pascal@15476
|
80 # endif
|
pascal@15188
|
81 # endif
|
pascal@15188
|
82 nocmdline:
|
pascal@15188
|
83 #endif
|
pascal@15472
|
84 movw $SYSSEG, %ax
|
pascal@15188
|
85 #ifdef CHECK_REALMODE
|
pascal@15188
|
86 #define PUTS
|
pascal@15188
|
87 movw $EXEADRS(realmode_expected), %si
|
pascal@15188
|
88 pushfw // save flags
|
pascal@15188
|
89 // bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
pascal@15188
|
90 // flags 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF
|
pascal@15472
|
91 //movb $0x10, %ah // DF = IF = TF = 0
|
pascal@15188
|
92 pushw %ax
|
pascal@15188
|
93 popfw // < 286 : flags[12..15] are forced 1
|
pascal@15188
|
94 pushfw // = 286 : flags[12..15] are forced 0
|
pascal@15469
|
95 popw %dx // > 286 : only flags[15] is forced 0
|
pascal@15188
|
96 popfw // restore flags
|
pascal@15469
|
97 addb %ah, %dh // test F0 and 00 cases
|
pascal@15469
|
98 cmpb %ah, %dh
|
pascal@15476
|
99 jeputs:
|
pascal@15188
|
100 jbe puts // C=8086/80186, Z=80286
|
pascal@15472
|
101 smsww %dx
|
pascal@15472
|
102 shrw $1, %dx
|
pascal@15472
|
103 jc puts
|
pascal@15188
|
104 #endif
|
pascal@15188
|
105 movw $0x100, %si
|
pascal@15188
|
106 movw $end_header, %di
|
pascal@15188
|
107 movb EXEADRS(setup_sects), %ch
|
pascal@15188
|
108 movb $(512-(end_header-_start))/2, %cl
|
pascal@15188
|
109 rep
|
pascal@15188
|
110 movsw
|
pascal@15188
|
111 ljmp $INITSEG, $movesys
|
pascal@15188
|
112 start:
|
pascal@15188
|
113 pushw %dx
|
pascal@15188
|
114 #else
|
pascal@15188
|
115 #undef HELP
|
pascal@15188
|
116 #undef CMDLINE
|
pascal@15188
|
117 #undef CHECK_REALMODE
|
pascal@15188
|
118 #endif
|
pascal@15188
|
119 cld # assume nothing
|
pascal@15188
|
120 stacktop = 0x9E00 # in 0x8000 .. 0xA000
|
pascal@15188
|
121 zeroed = 12 # zeroed registers
|
pascal@15188
|
122 movw $stacktop-12-zeroed, %di # stacktop is an arbitrary value >=
|
pascal@15188
|
123 # length of bootsect + length of
|
pascal@15188
|
124 # setup + room for stack;
|
pascal@15188
|
125 # 12 is disk parm size.
|
pascal@15188
|
126 pushw $INITSEG
|
pascal@15188
|
127 popw %ss # %ss contain INITSEG
|
pascal@15188
|
128 movw %di, %sp # put stack at INITSEG:stacktop-...
|
pascal@15188
|
129
|
pascal@15188
|
130 # Many BIOS's default disk parameter tables will not recognize
|
pascal@15188
|
131 # multi-sector reads beyond the maximum sector number specified
|
pascal@15188
|
132 # in the default diskette parameter tables - this may mean 7
|
pascal@15188
|
133 # sectors in some cases.
|
pascal@15188
|
134 #
|
pascal@15188
|
135 # Since single sector reads are slow and out of the question,
|
pascal@15188
|
136 # we must take care of this by creating new parameter tables
|
pascal@15188
|
137 # (for the first disk) in RAM. We can set the maximum sector
|
pascal@15188
|
138 # count to 36 - the most we will encounter on an ED 2.88.
|
pascal@15188
|
139 #
|
pascal@15188
|
140 # High doesn't hurt. Low does. Let's use the max: 63
|
pascal@15188
|
141
|
pascal@15188
|
142 pushw %ss
|
pascal@15188
|
143 popw %es # %es = %ss = INITSEG
|
pascal@15188
|
144 xorw %ax, %ax # %ax = 0
|
pascal@15472
|
145 #ifdef EXE_SUPPORT
|
pascal@15472
|
146 cwd # %dx = 0
|
pascal@15472
|
147 #endif
|
pascal@15188
|
148 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
|
pascal@15188
|
149 rep # don't worry about cld
|
pascal@15188
|
150 stosw # already done above
|
pascal@15188
|
151 popw %bx # offset = 0
|
pascal@15188
|
152 popw %ds # %ds = 0
|
pascal@15188
|
153 popw %fs # %fs = 0
|
pascal@15188
|
154
|
pascal@15188
|
155 movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0)
|
pascal@15188
|
156 incw %ax
|
pascal@15188
|
157
|
pascal@15188
|
158 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
|
pascal@15188
|
159 pushw %es
|
pascal@15188
|
160 pushw %di
|
pascal@15188
|
161 movb $6, %cl # copy 12 bytes
|
pascal@15188
|
162 rep # don't worry about cld
|
pascal@15188
|
163 movsw # already done above
|
pascal@15188
|
164 pushw %ss
|
pascal@15188
|
165 popw %ds # now %ds = %es = %ss = INITSEG
|
pascal@15188
|
166 popl %fs:0x78(%bx) # update parameter table address
|
pascal@15188
|
167 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
|
pascal@15188
|
168 cli
|
pascal@15188
|
169
|
pascal@15188
|
170 xchg %ax, %di # sector count
|
pascal@15188
|
171 popw %ax # limits = 0
|
pascal@15188
|
172 incw %cx # cylinder 0, sector 1, clear Z
|
pascal@15188
|
173 call read_first_sectors # read setup
|
pascal@15188
|
174
|
pascal@15188
|
175 # This routine loads the system at address LOADSEG, making sure
|
pascal@15188
|
176 # no 64kB boundaries are crossed. We try to load it as fast as
|
pascal@15188
|
177 # possible, loading whole tracks whenever we can.
|
pascal@15188
|
178
|
pascal@15188
|
179 popw %bx # clear %bx
|
pascal@15188
|
180 movw syssize, %di
|
pascal@15188
|
181 addw $(512/16)-1, %di
|
pascal@15188
|
182 shrw $9-4, %di
|
pascal@15188
|
183 movw $SYSSEG, %cx
|
pascal@15188
|
184 call read_sectorsCX
|
pascal@15188
|
185
|
pascal@15188
|
186 # This procedure turns off the floppy drive motor, so
|
pascal@15188
|
187 # that we enter the kernel in a known state, and
|
pascal@15188
|
188 # don't have to worry about it later.
|
pascal@15188
|
189
|
pascal@15188
|
190 kill_motor:
|
pascal@15188
|
191 xchgw %ax, %di # reset FDC (%di < 128)
|
pascal@15188
|
192 int $0x13
|
pascal@15188
|
193
|
pascal@15188
|
194 # After that (everything loaded), we jump to the setup-routine
|
pascal@15188
|
195 # loaded directly after the bootblock:
|
pascal@15188
|
196 # Segments are as follows: %ds = %ss = INITSEG
|
pascal@15188
|
197
|
pascal@15188
|
198 jmp_setup:
|
pascal@15188
|
199 ljmp $SETUPSEG, $0
|
pascal@15188
|
200
|
pascal@15188
|
201 #ifdef PUTS
|
pascal@15188
|
202 #define PUTC
|
pascal@15472
|
203 putslp:
|
pascal@15472
|
204 call putc
|
pascal@15188
|
205 puts:
|
pascal@15188
|
206 lodsb
|
pascal@15188
|
207 orb %al, %al
|
pascal@15472
|
208 jne putslp
|
pascal@15472
|
209 ret
|
pascal@15188
|
210 #endif
|
pascal@15188
|
211 #ifdef EXE_SUPPORT
|
pascal@15188
|
212 movesys:
|
pascal@15188
|
213 pushw %es
|
pascal@15188
|
214 popw %ss
|
pascal@15188
|
215 movw EXEADRS(syssize), %bp // %ds untouched
|
pascal@15188
|
216 movw %ds, %bx
|
pascal@15188
|
217 cwd
|
pascal@15188
|
218 incw %dx
|
pascal@15188
|
219 cmpw %ax, %bx
|
pascal@15188
|
220 jnc forward
|
pascal@15188
|
221 negw %dx
|
pascal@15188
|
222 addw %bp, %ax
|
pascal@15188
|
223 addw %bp, %bx
|
pascal@15188
|
224 forward:
|
pascal@15188
|
225 movw %ax, %es
|
pascal@15188
|
226 movw %bx, %ds
|
pascal@15188
|
227 xorw %di, %di
|
pascal@15188
|
228 movb $8, %cl
|
pascal@15472
|
229 pushw %si
|
pascal@15188
|
230 rep
|
pascal@15188
|
231 movsw
|
pascal@15472
|
232 popw %si
|
pascal@15188
|
233 addw %dx, %ax
|
pascal@15188
|
234 addw %dx, %bx
|
pascal@15188
|
235 decw %bp
|
pascal@15188
|
236 jns forward
|
pascal@15188
|
237 #ifndef NO_CURSOR_DEFINITION
|
pascal@15188
|
238 movb $1, %ah
|
pascal@15188
|
239 movb $0, %bh
|
pascal@15188
|
240 movb $0x20, %ch // 0x2000
|
pascal@15188
|
241 int $0x10
|
pascal@15188
|
242 #endif
|
pascal@15188
|
243 pushw %ss
|
pascal@15188
|
244 popw %ds
|
pascal@15188
|
245 jmp jmp_setup
|
pascal@15188
|
246 #endif
|
pascal@15188
|
247 putcdot:
|
pascal@15188
|
248 #ifdef PUTC
|
pascal@15188
|
249 movb $0x2E, %al
|
pascal@15188
|
250 putc:
|
pascal@15188
|
251 movb $0xE, %ah
|
pascal@15188
|
252 movw $7, %bx
|
pascal@15188
|
253 int $0x10
|
pascal@15188
|
254 #endif
|
pascal@15188
|
255 ret
|
pascal@15188
|
256
|
pascal@15188
|
257
|
pascal@15188
|
258 # read_sectors reads %di sectors into %es:0 buffer.
|
pascal@15188
|
259 # %es:0 is updated to the next memory location.
|
pascal@15188
|
260 # First, sectors are read sector by sector until
|
pascal@15188
|
261 # sector per track count is known. Then they are
|
pascal@15188
|
262 # read track by track.
|
pascal@15188
|
263 # Assume no error on first track.
|
pascal@15188
|
264
|
pascal@15188
|
265 #ifdef FLOPPY_1440K_ONLY
|
pascal@15188
|
266 #define FLOPPY_HEADS 2 /* 2 heads */
|
pascal@15188
|
267 #define FLOPPY_SECTORS 18 /* 18 sectors */
|
pascal@15188
|
268 #else
|
pascal@15188
|
269 #define FLOPPY_HEADS 2 /* 2 heads minimum */
|
pascal@15188
|
270 #define FLOPPY_SECTORS 9 /* 9 sectors minimum */
|
pascal@15188
|
271 #endif
|
pascal@15188
|
272
|
pascal@15188
|
273 check_limits:
|
pascal@15188
|
274 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
275 popw %dx
|
pascal@15188
|
276 #ifdef FLOPPY_SECTORS
|
pascal@15188
|
277 cmpb $FLOPPY_SECTORS+1, %cl # minimum sector count
|
pascal@15188
|
278 jb check_head
|
pascal@15188
|
279 #endif
|
pascal@15188
|
280 cmpb %al, %cl # max sector known ?
|
pascal@15188
|
281 ja next_head # no -> store it
|
pascal@15188
|
282 check_head:
|
pascal@15188
|
283 #ifdef FLOPPY_HEADS
|
pascal@15188
|
284 cmpb $FLOPPY_HEADS, %dh # 2 heads minimum
|
pascal@15188
|
285 jb check_cylinder
|
pascal@15188
|
286 #endif
|
pascal@15188
|
287 cmpb %ah, %dh # max head known ?
|
pascal@15188
|
288 ja next_cylinder # no -> store it
|
pascal@15188
|
289 check_cylinder:
|
pascal@15188
|
290 #endif
|
pascal@15188
|
291 pushaw
|
pascal@15188
|
292 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
293 cbw # %ah = 0
|
pascal@15188
|
294 #endif
|
pascal@15188
|
295 int $0x13 # reset controler
|
pascal@15188
|
296 popaw
|
pascal@15188
|
297 movb $1, %al # sector by sector...
|
pascal@15188
|
298 read_sectorslp:
|
pascal@15188
|
299 pushw %dx # some bios break dx...
|
pascal@15188
|
300 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
301 pushw %ax # limits
|
pascal@15188
|
302 subb %cl, %al # sectors remaining in track
|
pascal@15188
|
303 ja tolastsect
|
pascal@15188
|
304 movb $1, %al # 1 sector mini
|
pascal@15188
|
305 tolastsect:
|
pascal@15188
|
306 #else
|
pascal@15188
|
307 mov $FLOPPY_SECTORS+1, %al
|
pascal@15188
|
308 subb %cl, %al # sectors remaining in track
|
pascal@15188
|
309 #endif
|
pascal@15188
|
310 cbw
|
pascal@15188
|
311 cmpw %di, %ax
|
pascal@15188
|
312 jb more1trk
|
pascal@15188
|
313 movw %di, %ax # sectors to read
|
pascal@15188
|
314 more1trk:
|
pascal@15188
|
315 pushw %ax # save context
|
pascal@15188
|
316 movb $2, %ah # cmd: read chs
|
pascal@15188
|
317 int $0x13
|
pascal@15188
|
318 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
319 popw %dx # save %ax
|
pascal@15188
|
320 popw %ax # limits
|
pascal@15188
|
321 #else
|
pascal@15188
|
322 popw %ax # restore context
|
pascal@15188
|
323 popw %dx
|
pascal@15188
|
324 #endif
|
pascal@15188
|
325 jc check_limits
|
pascal@15188
|
326 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
327 xchgw %ax, %bp
|
pascal@15188
|
328 addw %dx,%cx # next sector
|
pascal@15188
|
329 movw %cx, %gs
|
pascal@15188
|
330 movw %es, %cx
|
pascal@15188
|
331 pushw %dx
|
pascal@15188
|
332 shlw $5, %dx
|
pascal@15188
|
333 addw %dx, %cx
|
pascal@15188
|
334 popw %dx
|
pascal@15188
|
335 subw %dx,%di # update sector counter
|
pascal@15188
|
336 popw %dx
|
pascal@15188
|
337 read_sectorsCX:
|
pascal@15188
|
338 movw %cx, %es # next location
|
pascal@15188
|
339 jz putcdot
|
pascal@15188
|
340 #else
|
pascal@15188
|
341 addw %ax,%cx # next sector
|
pascal@15188
|
342 movw %cx, %gs
|
pascal@15188
|
343 movw %es, %cx
|
pascal@15188
|
344 pushw %ax
|
pascal@15188
|
345 shlw $5, %ax
|
pascal@15188
|
346 addw %ax, %cx
|
pascal@15188
|
347 popw %ax
|
pascal@15188
|
348 subw %ax,%di # update sector counter
|
pascal@15188
|
349 read_sectorsCX:
|
pascal@15188
|
350 movw %cx, %es # next location
|
pascal@15188
|
351 jz putcdot
|
pascal@15188
|
352 #endif
|
pascal@15188
|
353 read_sectors:
|
pascal@15188
|
354 movw %gs, %cx
|
pascal@15188
|
355 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
356 # al is last sector+1
|
pascal@15188
|
357 # ah is last cylinder+1
|
pascal@15188
|
358 xchgw %ax, %bp
|
pascal@15188
|
359 #endif
|
pascal@15188
|
360 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
361 cmpb %al,%cl # reach sector limit ?
|
pascal@15188
|
362 jne bdendlp
|
pascal@15188
|
363 next_head:
|
pascal@15188
|
364 movb %cl,%al
|
pascal@15188
|
365 #else
|
pascal@15188
|
366 cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
|
pascal@15188
|
367 jne bdendlp
|
pascal@15188
|
368 #endif
|
pascal@15188
|
369 incb %dh # next head
|
pascal@15188
|
370 movb $1,%cl # first sector
|
pascal@15188
|
371 #ifndef FLOPPY_1440K_ONLY
|
pascal@15188
|
372 cmpb %ah, %dh # reach head limit ?
|
pascal@15188
|
373 jne bdendlp
|
pascal@15188
|
374 next_cylinder:
|
pascal@15188
|
375 movb %dh,%ah
|
pascal@15188
|
376 #else
|
pascal@15188
|
377 cmpb %cl,%dh # reach head limit ?
|
pascal@15188
|
378 je bdendlp
|
pascal@15188
|
379 #endif
|
pascal@15188
|
380 # NOTE : support 256 cylinders max
|
pascal@15188
|
381 incb %ch # next cylinder
|
pascal@15188
|
382 read_first_sectors:
|
pascal@15188
|
383 movb $0,%dh # first head
|
pascal@15188
|
384 bdendlp:
|
pascal@15188
|
385 jmp read_sectorslp
|
pascal@15188
|
386
|
pascal@15188
|
387 #ifdef CHECK_REALMODE
|
pascal@15188
|
388 realmode_expected:
|
pascal@15188
|
389 .ascii "386 real mode only."
|
pascal@15188
|
390 .byte 13,10,0
|
pascal@15188
|
391 #endif
|
pascal@15188
|
392 #ifdef HELP
|
pascal@15188
|
393 helpmsg:
|
pascal@15188
|
394 .ascii "No help available."
|
pascal@15188
|
395 .byte 13,10
|
pascal@15188
|
396 .byte 0
|
pascal@15188
|
397 #endif
|
pascal@15188
|
398 .org 497
|