rev |
line source |
pascal@538
|
1 --- etherboot-5.4.3/src/arch/i386/prefix/liloprefix.S
|
pascal@538
|
2 +++ etherboot-5.4.3/src/arch/i386/prefix/liloprefix.S
|
pascal@540
|
3 @@ -1,92 +1,393 @@
|
pascal@538
|
4 -/*
|
pascal@538
|
5 - Copyright (C) 2000, Entity Cyber, Inc.
|
pascal@538
|
6 -
|
pascal@538
|
7 - Authors: Gary Byers (gb@thinguin.org)
|
pascal@538
|
8 - Marty Connor (mdc@thinguin.org)
|
pascal@538
|
9 -
|
pascal@538
|
10 - This software may be used and distributed according to the terms
|
pascal@538
|
11 - of the GNU Public License (GPL), incorporated herein by reference.
|
pascal@538
|
12 -
|
pascal@538
|
13 - Description:
|
pascal@538
|
14 -
|
pascal@538
|
15 - This is just a little bit of code and data that can get prepended
|
pascal@538
|
16 - to an Etherboot ROM image in order to allow LILO to load the
|
pascal@538
|
17 - result as if it were a Linux kernel image.
|
pascal@538
|
18 -
|
pascal@538
|
19 - A real Linux kernel image consists of a one-sector boot loader
|
pascal@538
|
20 - (to load the image from a floppy disk), followed a few sectors
|
pascal@538
|
21 - of setup code, followed by the kernel code itself. There's
|
pascal@538
|
22 - a table in the first sector (starting at offset 497) that indicates
|
pascal@538
|
23 - how many sectors of setup code follow the first sector and which
|
pascal@538
|
24 - contains some other parameters that aren't interesting in this
|
pascal@538
|
25 - case.
|
pascal@538
|
26 -
|
pascal@538
|
27 - When LILO loads the sectors that comprise a kernel image, it doesn't
|
pascal@538
|
28 - execute the code in the first sector (since that code would try to
|
pascal@538
|
29 - load the image from a floppy disk.) The code in the first sector
|
pascal@538
|
30 - below doesn't expect to get executed (and prints an error message
|
pascal@538
|
31 - if it ever -is- executed.) LILO's only interested in knowing the
|
pascal@538
|
32 - number of setup sectors advertised in the table (at offset 497 in
|
pascal@538
|
33 - the first sector.)
|
pascal@538
|
34 -
|
pascal@538
|
35 - Etherboot doesn't require much in the way of setup code.
|
pascal@538
|
36 - Historically, the Linux kernel required at least 4 sectors of
|
pascal@538
|
37 - setup code. Current versions of LILO look at the byte at
|
pascal@538
|
38 - offset 497 in the first sector to indicate how many sectors
|
pascal@538
|
39 - of setup code are contained in the image.
|
pascal@538
|
40 -
|
pascal@538
|
41 -*/
|
pascal@538
|
42 +/* NOTE: this boot sector contains instructions that need at least an 80186.
|
pascal@538
|
43 + * Yes, as86 has a bug somewhere in the valid instruction set checks.
|
pascal@538
|
44 + *
|
pascal@538
|
45 + * SYS_SIZE is the number of clicks (16 bytes) to be loaded. For Etherboot
|
pascal@538
|
46 + * purposes, we need to load everything but the boot sector itself, i.e. 32
|
pascal@538
|
47 + * clicks less than the size of the entire (verbatim) image. The image size
|
pascal@538
|
48 + * is practically limited only by the available base memory size.
|
pascal@538
|
49 + */
|
pascal@538
|
50 +.globl SYSSIZE
|
pascal@538
|
51 +.equ SYSSIZE, _verbatim_size_pgh - 32
|
pascal@538
|
52 +
|
pascal@538
|
53 +/* floppyload.S Copyright (C) 1991, 1992 Linus Torvalds
|
pascal@538
|
54 + * modified by Drew Eckhardt
|
pascal@538
|
55 + * modified by Bruce Evans (bde)
|
pascal@538
|
56 + *
|
pascal@538
|
57 + * floppyprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
|
pascal@538
|
58 + *
|
pascal@538
|
59 + * It then loads the system at SYSSEG<<4, using BIOS interrupts.
|
pascal@538
|
60 + *
|
pascal@538
|
61 + * The loader has been made as simple as possible, and continuous read errors
|
pascal@538
|
62 + * will result in a unbreakable loop. Reboot by hand. It loads pretty fast by
|
pascal@538
|
63 + * getting whole tracks at a time whenever possible.
|
pascal@538
|
64 + */
|
pascal@538
|
65
|
pascal@538
|
66 #define SETUPSECS 4 /* Minimal nr of setup-sectors */
|
pascal@538
|
67 #define PREFIXSIZE ((SETUPSECS+1)*512)
|
pascal@538
|
68 #define PREFIXPGH (PREFIXSIZE / 16 )
|
pascal@538
|
69 -#define BOOTSEG 0x07C0 /* original address of boot-sector */
|
pascal@538
|
70 #define INITSEG 0x9000 /* we move boot here - out of the way */
|
pascal@538
|
71 #define SETUPSEG 0x9020 /* setup starts here */
|
pascal@538
|
72 -#define SYSSEG 0x1000 /* system loaded at 0x10000 (65536). */
|
pascal@538
|
73
|
pascal@538
|
74 - .text
|
pascal@538
|
75 - .code16
|
pascal@538
|
76 - .arch i386
|
pascal@538
|
77 - .org 0
|
pascal@538
|
78 - .section ".prefix", "ax", @progbits
|
pascal@538
|
79 .globl _prefix
|
pascal@538
|
80 _prefix:
|
pascal@538
|
81 +.equ BOOTSEG, 0x07C0 /* original address of boot-sector */
|
pascal@538
|
82
|
pascal@538
|
83 -/*
|
pascal@538
|
84 - This is a minimal boot sector. If anyone tries to execute it (e.g., if
|
pascal@538
|
85 - a .lilo file is dd'ed to a floppy), print an error message.
|
pascal@538
|
86 -*/
|
pascal@538
|
87 +.equ SYSSEG, 0x1000 /* system loaded at SYSSEG<<4 */
|
pascal@540
|
88 +
|
pascal@538
|
89 + .org 0
|
pascal@538
|
90 + .arch i386
|
pascal@538
|
91 + .text
|
pascal@538
|
92 + .section ".prefix", "ax", @progbits
|
pascal@538
|
93 + .code16
|
pascal@540
|
94
|
pascal@540
|
95 -bootsector:
|
pascal@540
|
96 - jmp $BOOTSEG, $go - _prefix /* reload cs:ip to match relocation addr */
|
pascal@540
|
97 + call here
|
pascal@540
|
98 +here:
|
pascal@540
|
99 + pop %ax
|
pascal@540
|
100 + cmpw $0x103, %ax /* COM entry point is cs:0x100 */
|
pascal@540
|
101 + jne bootsector
|
pascal@540
|
102 +/* We need a real mode stack that won't be stomped on by Etherboot
|
pascal@540
|
103 + which starts at 0x20000. Choose something that's sufficiently high,
|
pascal@540
|
104 + but not in DOC territory. Note that we couldn't do this in a real
|
pascal@540
|
105 + .com program since stack variables are in the same segment as the
|
pascal@540
|
106 + code and data, but this isn't really a .com program, it just looks
|
pascal@540
|
107 + like one to make DOS load it into memory. It still has the 64kB
|
pascal@540
|
108 + limitation of .com files though. */
|
pascal@540
|
109 +#define STACK_SEG 0x7000
|
pascal@540
|
110 +#define STACK_SIZE 0x4000
|
pascal@540
|
111 + /* Set up temporary stack */
|
pascal@540
|
112 + movw $STACK_SEG, %ax
|
pascal@540
|
113 + movw %ax, %ss
|
pascal@540
|
114 + movw $STACK_SIZE, %sp
|
pascal@538
|
115 +
|
pascal@540
|
116 + pushl $0 /* No parameters to preserve for exit path */
|
pascal@540
|
117 + pushw $0 /* Dummy return address - use prefix_exit */
|
pascal@540
|
118 +
|
pascal@540
|
119 + /* Calculate segment address of image start */
|
pascal@540
|
120 + pushw %cs
|
pascal@540
|
121 + popw %ax
|
pascal@540
|
122 + addw $(0x100/16), %ax
|
pascal@540
|
123 + pushw %ax
|
pascal@540
|
124 + pushw $_start
|
pascal@540
|
125 + /* Calculated lcall to _start with %cs:0000 = image start */
|
pascal@540
|
126 + lret
|
pascal@540
|
127 +
|
pascal@540
|
128 +bootsector:
|
pascal@538
|
129 + jmp $BOOTSEG, $go /* reload cs:ip to match relocation addr */
|
pascal@538
|
130 go:
|
pascal@538
|
131 - movw $0x2000, %di /* 0x2000 is arbitrary value >= length
|
pascal@538
|
132 - of bootsect + room for stack */
|
pascal@538
|
133 + movw $0x2000-12, %di /* 0x2000 is arbitrary value >= length */
|
pascal@538
|
134 + /* of bootsect + room for stack + 12 for */
|
pascal@538
|
135 + /* saved disk parm block */
|
pascal@538
|
136
|
pascal@538
|
137 movw $BOOTSEG, %ax
|
pascal@538
|
138 movw %ax,%ds
|
pascal@538
|
139 movw %ax,%es
|
pascal@538
|
140 -
|
pascal@538
|
141 - cli
|
pascal@538
|
142 - movw %ax, %ss /* put stack at BOOTSEG:0x2000. */
|
pascal@538
|
143 + movw %ax,%ss /* put stack at initial position */
|
pascal@538
|
144 movw %di,%sp
|
pascal@538
|
145 - sti
|
pascal@538
|
146
|
pascal@538
|
147 - movw $why_end-why, %cx
|
pascal@538
|
148 - movw $why - _prefix, %si
|
pascal@538
|
149 +/* Many BIOS's default disk parameter tables will not recognize multi-sector
|
pascal@538
|
150 + * reads beyond the maximum sector number specified in the default diskette
|
pascal@538
|
151 + * parameter tables - this may mean 7 sectors in some cases.
|
pascal@538
|
152 + *
|
pascal@538
|
153 + * Since single sector reads are slow and out of the question, we must take care
|
pascal@538
|
154 + * of this by creating new parameter tables (for the first disk) in RAM. We
|
pascal@538
|
155 + * will set the maximum sector count to 36 - the most we will encounter on an
|
pascal@538
|
156 + * ED 2.88. High doesn't hurt. Low does.
|
pascal@538
|
157 + *
|
pascal@538
|
158 + * Segments are as follows: ds=es=ss=cs - BOOTSEG
|
pascal@538
|
159 + */
|
pascal@538
|
160 +
|
pascal@538
|
161 + xorw %cx,%cx
|
pascal@538
|
162 + movw %cx,%es /* access segment 0 */
|
pascal@538
|
163 + movw $0x78, %bx /* 0:bx is parameter table address */
|
pascal@538
|
164 + pushw %ds /* save ds */
|
pascal@538
|
165 +/* 0:bx is parameter table address */
|
pascal@538
|
166 + ldsw %es:(%bx),%si /* loads ds and si */
|
pascal@538
|
167 +
|
pascal@538
|
168 + movw %ax,%es /* ax is BOOTSECT (loaded above) */
|
pascal@538
|
169 + movb $6, %cl /* copy 12 bytes */
|
pascal@538
|
170 + cld
|
pascal@538
|
171 + pushw %di /* keep a copy for later */
|
pascal@538
|
172 + rep
|
pascal@538
|
173 + movsw /* ds:si is source, es:di is dest */
|
pascal@538
|
174 + popw %di
|
pascal@538
|
175 +
|
pascal@538
|
176 + movb $36,%es:4(%di)
|
pascal@538
|
177 +
|
pascal@538
|
178 + movw %cx,%ds /* access segment 0 */
|
pascal@538
|
179 + xchgw %di,(%bx)
|
pascal@538
|
180 + movw %es,%si
|
pascal@538
|
181 + xchgw %si,2(%bx)
|
pascal@538
|
182 + popw %ds /* restore ds */
|
pascal@538
|
183 + movw %di, dpoff /* save old parameters */
|
pascal@538
|
184 + movw %si, dpseg /* to restore just before finishing */
|
pascal@538
|
185 + pushw %ds
|
pascal@538
|
186 + popw %es /* reload es */
|
pascal@538
|
187 +
|
pascal@538
|
188 +/* Note that es is already set up. Also cx is 0 from rep movsw above. */
|
pascal@538
|
189 +
|
pascal@538
|
190 + xorb %ah,%ah /* reset FDC */
|
pascal@538
|
191 + xorb %dl,%dl
|
pascal@538
|
192 + int $0x13
|
pascal@538
|
193 +
|
pascal@538
|
194 +/* Get disk drive parameters, specifically number of sectors/track.
|
pascal@538
|
195 + *
|
pascal@538
|
196 + * It seems that there is no BIOS call to get the number of sectors. Guess
|
pascal@538
|
197 + * 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
|
pascal@538
|
198 + * 15 if sector 15 can be read. Otherwise guess 9.
|
pascal@538
|
199 + */
|
pascal@538
|
200 +
|
pascal@538
|
201 + movw $disksizes, %si /* table of sizes to try */
|
pascal@538
|
202 +
|
pascal@538
|
203 +probe_loop:
|
pascal@538
|
204 + lodsb
|
pascal@538
|
205 + cbtw /* extend to word */
|
pascal@538
|
206 + movw %ax, sectors
|
pascal@538
|
207 + cmpw $disksizes+4, %si
|
pascal@538
|
208 + jae got_sectors /* if all else fails, try 9 */
|
pascal@538
|
209 + xchgw %cx,%ax /* cx = track and sector */
|
pascal@538
|
210 + xorw %dx,%dx /* drive 0, head 0 */
|
pascal@538
|
211 + movw $0x0200, %bx /* address after boot sector */
|
pascal@538
|
212 + /* (512 bytes from origin, es = cs) */
|
pascal@538
|
213 + movw $0x0201, %ax /* service 2, 1 sector */
|
pascal@538
|
214 + int $0x13
|
pascal@538
|
215 + jc probe_loop /* try next value */
|
pascal@538
|
216 +
|
pascal@538
|
217 +got_sectors:
|
pascal@538
|
218 + movw $msg1end-msg1, %cx
|
pascal@538
|
219 + movw $msg1, %si
|
pascal@538
|
220 + call print_str
|
pascal@538
|
221 +
|
pascal@538
|
222 +/* ok, we've written the Loading... message, now we want to load the system */
|
pascal@538
|
223 +
|
pascal@538
|
224 + pushw %es /* = ds */
|
pascal@538
|
225 + movw $SYSSEG, %ax
|
pascal@538
|
226 + movw %ax,%es /* segment of SYSSEG<<4 */
|
pascal@538
|
227 + pushw %es
|
pascal@538
|
228 + call read_it
|
pascal@538
|
229 +
|
pascal@538
|
230 +/* This turns off the floppy drive motor, so that we enter the kernel in a
|
pascal@538
|
231 + * known state, and don't have to worry about it later.
|
pascal@538
|
232 + */
|
pascal@538
|
233 + movw $0x3f2, %dx
|
pascal@538
|
234 + xorb %al,%al
|
pascal@538
|
235 + outb %al,%dx
|
pascal@538
|
236 +
|
pascal@538
|
237 + call print_nl
|
pascal@538
|
238 + pop %es /* = SYSSEG */
|
pascal@538
|
239 + pop %es /* balance push/pop es */
|
pascal@538
|
240 +sigok:
|
pascal@538
|
241 +
|
pascal@538
|
242 +/* Restore original disk parameters */
|
pascal@538
|
243 + movw $0x78, %bx
|
pascal@538
|
244 + movw dpoff, %di
|
pascal@538
|
245 + movw dpseg, %si
|
pascal@538
|
246 + xorw %ax,%ax
|
pascal@538
|
247 + movw %ax,%ds
|
pascal@538
|
248 + movw %di,(%bx)
|
pascal@538
|
249 + movw %si,2(%bx)
|
pascal@538
|
250 +
|
pascal@538
|
251 +/* after that (everything loaded), we call to the .ROM file loaded. */
|
pascal@538
|
252 +
|
pascal@538
|
253 + pushl $0 /* No parameters to preserve for exit path */
|
pascal@538
|
254 + pushw $0 /* Use prefix exit path mechanism */
|
pascal@538
|
255 + ljmp $SYSSEG, $_start
|
pascal@538
|
256 +
|
pascal@538
|
257 +/* This routine loads the system at address SYSSEG<<4, making sure no 64kB
|
pascal@538
|
258 + * boundaries are crossed. We try to load it as fast as possible, loading whole
|
pascal@538
|
259 + * tracks whenever we can.
|
pascal@538
|
260 + *
|
pascal@538
|
261 + * in: es - starting address segment (normally SYSSEG)
|
pascal@538
|
262 + */
|
pascal@538
|
263 +read_it:
|
pascal@538
|
264 + movw $0,sread /* read whole image incl boot sector */
|
pascal@538
|
265 + movw %es,%ax
|
pascal@538
|
266 + testw $0x0fff, %ax
|
pascal@538
|
267 +die: jne die /* es must be at 64kB boundary */
|
pascal@538
|
268 + xorw %bx,%bx /* bx is starting address within segment */
|
pascal@538
|
269 +rp_read:
|
pascal@538
|
270 + movw %es,%ax
|
pascal@538
|
271 + movw %bx,%dx
|
pascal@538
|
272 + movb $4, %cl
|
pascal@538
|
273 + shrw %cl,%dx /* bx is always divisible by 16 */
|
pascal@538
|
274 + addw %dx,%ax
|
pascal@538
|
275 + cmpw $SYSSEG+SYSSIZE, %ax /* have we loaded all yet? */
|
pascal@538
|
276 + jb ok1_read
|
pascal@538
|
277 + ret
|
pascal@538
|
278 +ok1_read:
|
pascal@538
|
279 + movw sectors, %ax
|
pascal@538
|
280 + subw sread, %ax
|
pascal@538
|
281 + movw %ax,%cx
|
pascal@538
|
282 + shlw $9, %cx
|
pascal@538
|
283 + addw %bx,%cx
|
pascal@538
|
284 + jnc ok2_read
|
pascal@538
|
285 + je ok2_read
|
pascal@538
|
286 + xorw %ax,%ax
|
pascal@538
|
287 + subw %bx,%ax
|
pascal@538
|
288 + shrw $9, %ax
|
pascal@538
|
289 +ok2_read:
|
pascal@538
|
290 + call read_track
|
pascal@538
|
291 + movw %ax,%cx
|
pascal@538
|
292 + addw sread, %ax
|
pascal@538
|
293 + cmpw sectors, %ax
|
pascal@538
|
294 + jne ok3_read
|
pascal@538
|
295 + movw $1, %ax
|
pascal@538
|
296 + subw head, %ax
|
pascal@538
|
297 + jne ok4_read
|
pascal@538
|
298 + incw track
|
pascal@538
|
299 +ok4_read:
|
pascal@538
|
300 + movw %ax, head
|
pascal@538
|
301 + xorw %ax,%ax
|
pascal@538
|
302 +ok3_read:
|
pascal@538
|
303 + movw %ax, sread
|
pascal@538
|
304 + shlw $9, %cx
|
pascal@538
|
305 + addw %cx,%bx
|
pascal@538
|
306 + jnc rp_read
|
pascal@538
|
307 + movw %es,%ax
|
pascal@538
|
308 + addb $0x10, %ah
|
pascal@538
|
309 + movw %ax,%es
|
pascal@538
|
310 + xorw %bx,%bx
|
pascal@538
|
311 + jmp rp_read
|
pascal@538
|
312 +
|
pascal@538
|
313 +read_track:
|
pascal@538
|
314 + pusha
|
pascal@538
|
315 + pushw %ax
|
pascal@538
|
316 + pushw %bx
|
pascal@538
|
317 + pushw %bp /* just in case the BIOS is buggy */
|
pascal@538
|
318 + movw $0x0e2e, %ax /* 0x2e = . */
|
pascal@538
|
319 + movw $0x0007, %bx
|
pascal@538
|
320 + int $0x10
|
pascal@538
|
321 + popw %bp
|
pascal@538
|
322 + popw %bx
|
pascal@538
|
323 + popw %ax
|
pascal@538
|
324 +
|
pascal@538
|
325 + movw track, %dx
|
pascal@538
|
326 + movw sread, %cx
|
pascal@538
|
327 + incw %cx
|
pascal@538
|
328 + movb %dl,%ch
|
pascal@538
|
329 + movw head, %dx
|
pascal@538
|
330 + movb %dl,%dh
|
pascal@538
|
331 + andw $0x0100, %dx
|
pascal@538
|
332 + movb $2, %ah
|
pascal@538
|
333 +
|
pascal@538
|
334 + pushw %dx /* save for error dump */
|
pascal@538
|
335 + pushw %cx
|
pascal@538
|
336 + pushw %bx
|
pascal@538
|
337 + pushw %ax
|
pascal@538
|
338 +
|
pascal@538
|
339 + int $0x13
|
pascal@538
|
340 + jc bad_rt
|
pascal@538
|
341 + addw $8, %sp
|
pascal@538
|
342 + popa
|
pascal@538
|
343 + ret
|
pascal@538
|
344 +
|
pascal@538
|
345 +bad_rt: pushw %ax /* save error code */
|
pascal@538
|
346 + call print_all /* ah = error, al = read */
|
pascal@538
|
347 +
|
pascal@538
|
348 + xorb %ah,%ah
|
pascal@538
|
349 + xorb %dl,%dl
|
pascal@538
|
350 + int $0x13
|
pascal@538
|
351 +
|
pascal@538
|
352 + addw $10, %sp
|
pascal@538
|
353 + popa
|
pascal@538
|
354 + jmp read_track
|
pascal@538
|
355 +
|
pascal@538
|
356 +/* print_all is for debugging purposes. It will print out all of the registers.
|
pascal@538
|
357 + * The assumption is that this is called from a routine, with a stack frame like
|
pascal@538
|
358 + * dx
|
pascal@538
|
359 + * cx
|
pascal@538
|
360 + * bx
|
pascal@538
|
361 + * ax
|
pascal@538
|
362 + * error
|
pascal@538
|
363 + * ret <- sp
|
pascal@538
|
364 + */
|
pascal@538
|
365 +
|
pascal@538
|
366 +print_all:
|
pascal@538
|
367 + call print_nl /* nl for readability */
|
pascal@538
|
368 + movw $5, %cx /* error code + 4 registers */
|
pascal@538
|
369 + movw %sp,%bp
|
pascal@538
|
370 +
|
pascal@538
|
371 +print_loop:
|
pascal@538
|
372 + pushw %cx /* save count left */
|
pascal@538
|
373 +
|
pascal@538
|
374 + cmpb $5, %cl
|
pascal@538
|
375 + jae no_reg /* see if register name is needed */
|
pascal@538
|
376
|
pascal@538
|
377 movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
pascal@538
|
378 + movw $0xe05+0x41-1, %ax
|
pascal@538
|
379 + subb %cl,%al
|
pascal@538
|
380 + int $0x10
|
pascal@538
|
381 +
|
pascal@538
|
382 + movb $0x58, %al /* 'X' */
|
pascal@538
|
383 + int $0x10
|
pascal@538
|
384 +
|
pascal@538
|
385 + movb $0x3A, %al /* ':' */
|
pascal@538
|
386 + int $0x10
|
pascal@538
|
387 +
|
pascal@538
|
388 +no_reg:
|
pascal@538
|
389 + addw $2, %bp /* next register */
|
pascal@538
|
390 + call print_hex /* print it */
|
pascal@538
|
391 + movb $0x20, %al /* print a space */
|
pascal@538
|
392 + int $0x10
|
pascal@538
|
393 + popw %cx
|
pascal@538
|
394 + loop print_loop
|
pascal@538
|
395 + call print_nl /* nl for readability */
|
pascal@538
|
396 + ret
|
pascal@538
|
397 +
|
pascal@538
|
398 +print_str:
|
pascal@538
|
399 + movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
pascal@538
|
400 movb $0x0e, %ah /* write char, tty mode */
|
pascal@538
|
401 prloop:
|
pascal@538
|
402 lodsb
|
pascal@538
|
403 int $0x10
|
pascal@538
|
404 loop prloop
|
pascal@538
|
405 -freeze: jmp freeze
|
pascal@538
|
406 + ret
|
pascal@538
|
407 +
|
pascal@538
|
408 +print_nl:
|
pascal@538
|
409 + movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
pascal@538
|
410 + movw $0xe0d, %ax /* CR */
|
pascal@538
|
411 + int $0x10
|
pascal@538
|
412 + movb $0xa, %al /* LF */
|
pascal@538
|
413 + int $0x10
|
pascal@538
|
414 + ret
|
pascal@538
|
415 +
|
pascal@538
|
416 +/* print_hex prints the word pointed to by ss:bp in hexadecimal. */
|
pascal@538
|
417 +
|
pascal@538
|
418 +print_hex:
|
pascal@538
|
419 + movw (%bp),%dx /* load word into dx */
|
pascal@538
|
420 + movb $4, %cl
|
pascal@538
|
421 + movb $0x0e, %ah /* write char, tty mode */
|
pascal@538
|
422 + movw $0x0007, %bx /* page 0, attribute 7 (normal) */
|
pascal@540
|
423 + call print_digit2
|
pascal@540
|
424 +print_digit2:
|
pascal@538
|
425 + call print_digit
|
pascal@538
|
426 +/* fall through */
|
pascal@538
|
427 +print_digit:
|
pascal@538
|
428 + rol %cl,%dx /* rotate so that lowest 4 bits are used */
|
pascal@538
|
429 + movb $0x0f, %al /* mask for nybble */
|
pascal@538
|
430 + andb %dl,%al
|
pascal@538
|
431 + addb $0x90, %al /* convert al to ascii hex (four instructions) */
|
pascal@538
|
432 + daa
|
pascal@538
|
433 + adcb $0x40, %al
|
pascal@538
|
434 + daa
|
pascal@538
|
435 + int $0x10
|
pascal@538
|
436 + ret
|
pascal@538
|
437 +
|
pascal@538
|
438 +sread: .word 0 /* sectors read of current track */
|
pascal@538
|
439 +head: .word 0 /* current head */
|
pascal@538
|
440 +track: .word 0 /* current track */
|
pascal@538
|
441 +
|
pascal@538
|
442 +sectors:
|
pascal@538
|
443 + .word 0
|
pascal@538
|
444 +
|
pascal@538
|
445 +dpseg: .word 0
|
pascal@538
|
446 +dpoff: .word 0
|
pascal@538
|
447
|
pascal@538
|
448 -why: .ascii "This image cannot be loaded from a floppy disk.\r\n"
|
pascal@538
|
449 -why_end:
|
pascal@538
|
450 +disksizes:
|
pascal@538
|
451 + .byte 36,18,15,9
|
pascal@538
|
452
|
pascal@538
|
453 +msg1:
|
pascal@540
|
454 + .ascii "Loading ROM"
|
pascal@538
|
455 +msg1end:
|
pascal@538
|
456
|
pascal@538
|
457 .org 497
|
pascal@538
|
458 setup_sects:
|