wok-tiny view linux/stuff/bootloader.S @ rev 168

memtest: 386 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Apr 30 16:35:54 2021 +0000 (2021-04-30)
parents bb00d1e3b0f7
children eb617e43dc08
line source
1 BOOTSEG = 0x07C0 /* original address of boot-sector */
2 SYSSEG = 0x1000 /* historical load address >> 4 */
3 INITSEG = 0x9000 /* boot address >> 4 */
4 SETUPSEG = 0x9020 /* setup address >> 4 */
5 ASK_VGA = -3
7 #ifndef SVGA_MODE
8 #define SVGA_MODE ASK_VGA
9 #endif
11 #ifndef RAMDISK
12 #define RAMDISK 0
13 #endif
15 #ifndef ROOT_RDONLY
16 #define ROOT_RDONLY 1
17 #endif
19 /* Assume protocol 2.00+ (kernel >= 1.3.73) */
21 /* basic support: zImage or bzImage, floppy parameters table patch, */
22 /* any sectors/track count (720K, 1.2M, 1.44M floppy or 1.68M ...), */
23 /* show progress (.), show errors (-) */
25 /* extra feature set */
26 #define EXE_SUPPORT real mode dos .exe file support
27 #define EXE_CMDLINE kernel >= 2.4
28 // #define FLOPPY_CMDLINE kernel >= 2.4
29 // #define OLDCMDLINE kernel < 2.4
30 #define DISPLAY_VERSION display version string
31 #define MORETHAN16M up to 4Gb RAM, not 16Mb
32 #define KEYBOARDLESS_SUPPORT scan floppy swap each 5 seconds
33 // #define FAT12_SUPPORT will format the floppy free space in FAT 12
34 // #define CHECK_REALMODE exe dont crash when started in vm86
35 #define MULTI_FLOPPY Everything may dont fit in a single floppy
36 // #define EDIT_CMDLINE Wait 5 seconds for the first key to edit it
37 // #define MOVE_CMDLINE
38 #define INITRD_SUPPORT
39 // #define INITRD_AUTOADDR Hole in 16Mb..32Mb
40 // #define MULTI_INITRD Russian dolls
41 // #define README_SUPPORT
42 // #define COUNTER Show floppy number
43 #define LABEL "Tiny"
45 /* remove from basic features */
46 // #define EXE_ONLY remove floppy code
47 // #define NO_FLOPPY_TABLE_PATCH remove floppy parameter table patch
48 // #define NO_OUTPUT remove output code
50 .code16
51 .org 0
53 #ifdef NO_OUTPUT
54 # undef DISPLAY_VERSION
55 # undef README_SUPPORT
56 # undef FLOPPY_CMDLINE
57 # undef COUNTER
58 #endif
60 bootsect_start:
62 cur_initrd_size_ofs = 494
63 ramdisk_image_ofs = 0x218
64 ramdisk_image = bootsect_start+ramdisk_image_ofs
65 ramdisk_size_ofs = 0x21C
66 ramdisk_size = bootsect_start+ramdisk_size_ofs
67 cmd_line_ptr_ofs = 0x228
68 cmd_line_ptr = bootsect_start+cmd_line_ptr_ofs
69 setup_sects = bootsect_start+497
70 syssize = bootsect_start+500
71 boot_flag_ofs = 510
72 boot_flag = bootsect_start+boot_flag_ofs
75 stacktop = 0x9E00 # in 0x8000 .. 0xA000
76 #ifdef NO_FLOPPY_TABLE_PATCH
77 zeroed = 48+8 # gdt + zeroed registers
78 #else
79 zeroed = 48+10 # gdt + zeroed registers
80 #endif
81 .macro INIT_REGS
82 movw $stacktop-zeroed, %di # stacktop is an arbitrary value >=
83 # length of bootsect + length of
84 # setup + room for stack;
85 # 12 is disk parm size.
86 pushw $INITSEG
87 popw %ss # %ss contain INITSEG
88 movw %di, %sp # put stack at INITSEG:stacktop-...
89 pushw %ss
90 popw %es # %es = %ss = INITSEG
91 xorw %ax, %ax # %ax = 0
92 #ifdef EXE_CMDLINE
93 movw $zeroed+1, %cx # clear gdt + offset, %ds, limits, cmdline=""
94 rep # don't worry about cld
95 stosb # already done above
96 decw %di
97 #else
98 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
99 rep # don't worry about cld
100 stosw # already done above
101 #endif
102 popw %bx # offset = 0
103 .endm
105 #ifdef FAT12_SUPPORT
106 jmp fdstart
107 nop
108 .ascii "SLITAZ "
109 .word 512 // 0B: bytes per sector
110 .byte 1 // 0D: sectors per cluster
111 .word 2880 // 0E: reserved seectors
112 .byte 2 // 10: FAT number
113 .word 64 // 11: root entries 4x 16
114 .word 2880 // 13: total sectors
115 .byte 0xF0 // 15: media id (or F9)
116 #endif
118 #ifdef EXE_SUPPORT
119 #define CODESZ 0x8000
120 #define EXEADRS(x) x+0xE0
121 decw %bp // Magic number: MZ
122 popw %dx
123 #ifdef EXE_ONLY
124 .word 512 // Bytes on last page of file
125 #else
126 jmp fdstart // Bytes on last page of file
127 #endif
128 .word (CODESZ+511)/512 // Pages in file
129 .word 0 // Relocations
130 .word 2 // Size of header in paragraphs
131 .word 4096 // Minimum extra paragraphs needed
132 .word -1 // Maximum extra paragraphs needed
133 .word (CODESZ+15)/16 // Initial (relative) SS value
134 .word stacktop+4 // Initial SP value (+callf)
135 .word 0 // Checksum
136 .word EXEADRS(comstart) // Initial IP value
137 .word 0xFFF0 // Initial (relative) CS value
138 #if defined(EXE_ONLY) || !defined(MULTI_FLOPPY) || defined(COUNTER)
139 // .word 0x001C // File address of relocation table
140 // .word 0,0,0 // Overlay number
141 .ascii "(SliTaz)"
142 #else
143 swap_floppy:
144 .ascii "Next!"
145 .byte 7,13,0 # swap detection needs 13, 0
146 #endif
147 #ifdef OLDCMDLINE
148 # ifdef FLOPPY_CMDLINE
149 .word 0 # 0xA33F
150 .word 0 # stacktop
151 # else
152 .word 0xA33F
153 .word stacktop
154 # endif
155 #endif
156 #ifndef EXE_ONLY
157 fdstart:
158 pushw %dx
159 #endif
160 #endif
162 LOADSEG = 0x8000 # 0x1000 multiple, up to 512K zImage
163 LOADSZ = 0x10000
165 #if defined(EXE_SUPPORT) || defined(EXE_ONLY)
166 A20BUFFER = 0x68000 # a20 gate / himem.sys support
167 #define USEA20BUFFER # Does not break zImage support
168 #endif
170 #ifndef EXE_ONLY
171 # bootsect_start:
172 #ifdef EXE_SUPPORT
173 call initregs
174 cwd # floppy = head = 0
175 #else
176 INIT_REGS
177 #endif
178 popw %ds # %ds = 0
179 movb setup_sects+0x7C00, %al # read bootsector + setup
180 incw %ax # %ax = setup_sects+bootsect
181 popw %fs # %fs = 0
183 # Many BIOS's default disk parameter tables will not recognize
184 # multi-sector reads beyond the maximum sector number specified
185 # in the default diskette parameter tables - this may mean 7
186 # sectors in some cases.
187 #
188 # Since single sector reads are slow and out of the question,
189 # we must take care of this by creating new parameter tables
190 # (for the first disk) in RAM. We can set the maximum sector
191 # count to 36 - the most we will encounter on an ED 2.88.
192 #
193 # High doesn't hurt. Low does. Let's use the max: 63
195 cli
196 #ifdef NO_FLOPPY_TABLE_PATCH
197 xchg %ax, %di # sector count
198 popw %ax # limits = 0
199 incw %cx # cylinder 0, sector 1, clear Z
200 call read_first_sectors # read setup
201 # ifdef FLOPPY_CMDLINE
202 movw $0, %si # patched by installer (7C22)
203 skipcmdline:
204 #define cmd_line_ptr 0x22
205 # endif
206 #else
207 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
208 popw %di
209 pushw %es
210 pushw %di
211 # ifdef FLOPPY_CMDLINE
212 movw $0, %bp # patched by installer (7C22)
213 skipcmdline:
214 #define cmd_line_ptr 0x22
215 # endif
216 movb $6, %cl # copy 12 bytes
217 rep # don't worry about cld
218 movsw # already done above
219 pushw %ss
220 popw %ds # now %ds = %es = %ss = INITSEG
221 popl %fs:0x78(%bx) # update parameter table address
222 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
224 xchg %ax, %di # sector count
225 popw %ax # limits = 0
226 incw %cx # cylinder 0, sector 1, clear Z
227 call read_first_sectors # read setup
228 #endif
229 #ifdef README_SUPPORT
230 xorw %si, %si
231 orw readme, %si
232 jz readmeend
233 readmeloop:
234 call puts
235 jz readmeend
236 call wait4key
237 cmpb $27, %al
238 jne readmeloop
239 readmeend:
240 #endif
241 #endif
242 loadsys:
243 movw $0x200,%si
244 type_of_loader = 0x10
245 loadflags = 0x11
246 heap_end_ptr = 0x24
247 orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
248 movb $(stacktop-0x300)/256, heap_end_ptr+1(%si)
249 #ifdef DISPLAY_VERSION
250 call puts_version # show which kernel we are loading
251 #endif
253 #ifdef FLOPPY_CMDLINE
254 # The cmdline can be entered and modifed at boot time.
255 # Only characters before the cursor are passed to the kernel.
257 xorw %si, %si
258 orw cmd_line_ptr-7(%bx), %si
259 jz nocmdline
260 #ifdef OLDCMDLINE
261 movw $0xA33F, cmd_line_ptr-2-7(%bx)
262 #endif
263 call puts
264 #ifdef EDIT_CMDLINE
265 cmdlp:
266 movb $0x20, %al # clear end of line
267 cmdlpz:
268 call putc # with Space
269 subb $0x18, %al # and BackSpace
270 jnc cmdlpz
271 decw %si
272 cmdget:
273 #ifdef KEYBOARDLESS_SUPPORT
274 call wait4key
275 #else
276 int $0x16
277 cbw # %ah = 0, get keyboard character
278 #endif
279 cmpb $8, %al # BackSpace ?
280 je cmdbs
281 movb %al, (%si) # store char
282 lodsw # %si += 2
283 cmdbs:
284 cmpw %si, cmd_line_ptr-7(%bx)
285 je cmdget
286 call putc
287 cmpb $10, %al # Enter/linefeed ?
288 jne cmdlp
289 movb %bh,-2(%si) # set end of string and remove CR
290 endcmdline:
291 #endif
292 #ifdef MOVE_CMDLINE
293 pushw %ss
294 popw %es
295 movw $0x8000, %di
296 movw %di, %si
297 xchgw %si, cmd_line_ptr-7(%bx)
298 movb $0x2, %ch
299 rep
300 movsb
301 #endif
302 nocmdline:
303 #endif
305 # This routine loads the system at address LOADSEG, making sure
306 # no 64kB boundaries are crossed. We try to load it as fast as
307 # possible, loading whole tracks whenever we can.
309 .macro autoaddr base
310 movb $0x88, %ah
311 int $0x15
312 //jc NeedMoreRAM # error code 80 or 86
313 cmpw $0xB000, %ax # more than 45M ?
314 jb NeedMoreRAM
315 movb %ch, bootsect_dst_base_hi(%si) # initramfs @ 32M
316 movb %ch, ramdisk_image_ofs+3-\base
317 NeedMoreRAM:
318 .endm
320 bootsect_src_limit = 16
321 bootsect_dst_limit = 24
322 bootsect_src_base = 18
323 bootsect_dst_base = 26 # bits 0..23
324 bootsect_dst_base_hi = 31 # bits 24..31
325 popw %bx # clear %bx
326 movw %sp, %si # for bootsect_gdt
327 init_gdt:
328 decw bootsect_src_limit(%bx,%si) # max 64Kb
329 movw $0x9300+(LOADSEG/0x1000), bootsect_src_base+2(%bx,%si)
330 xorb $bootsect_dst_limit-bootsect_src_limit, %bl
331 jne init_gdt
332 #ifdef INITRD_SUPPORT
333 movw $syssize, %bx
334 movb $5, %cl
335 code32_start = 0x214
336 movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000
337 initrdlp:
338 movl (%bx), %ebx
339 decl %ebx
340 shrl %cl, %ebx
341 #else
342 code32_start = 0x214
343 movw code32_start+1, %ax # destination = 0x00100000 or 0x00010000
344 movl syssize, %ebx
345 decl %ebx
346 shrl $5, %ebx
347 #endif
348 #ifdef MORETHAN16M
349 incl %ebx
350 #else
351 incw %bx
352 #endif
353 #ifdef USEA20BUFFER
354 movw $0x00100000>>8, %di
355 #endif
356 syslp:
357 #ifdef USEA20BUFFER
358 cmpw %ax, %di
359 jne nota20
360 xorw $(0x00100000+A20BUFFER)>>8, %ax
361 nota20:
362 #endif
363 movw %ax, bootsect_dst_base+1(%si)
364 #ifdef MORETHAN16M
365 movl $LOADSZ/512, %edi # size in sectors
366 subl %edi, %ebx
367 #else
368 movw $LOADSZ/512, %di # size in sectors
369 subw %di, %bx
370 #endif
371 pushf
372 jnc not_last
373 addw %bx, %di
374 not_last:
375 #ifdef MULTI_INITRD
376 pushw %di
377 #endif
378 pushw %ax
379 pushw %bx
380 pushw %si
381 xorw %bx,%bx
382 pushw $LOADSEG
383 popw %es
384 #ifdef EXE_ONLY
385 call read_sectors_dos
386 #else
387 patchcall:
388 call read_sectors # update %bp
389 #endif
390 popw %si
391 popw %bx
392 movw %es, %cx # word count = LOADSZ/2 (= LOADSEG)
393 movb $0x87, %ah
394 pushw %ss
395 popw %es # restore es
396 int $0x15 # max 16M, maybe more...
397 popw %ax
398 #ifdef MULTI_INITRD
399 popw %di
400 shlw $1,%di # sectors to pages
401 addw %di, %ax
402 #ifdef MORETHAN16M
403 adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ?
404 #endif
405 #else
406 #ifdef MORETHAN16M
407 addw $0x100, %ax # next dest (ax+=LOADSZ/256)
408 adcb %cl, bootsect_dst_base_hi(%si) # breaks 16M limit ?
409 #else
410 incb %ah # next dest (ax+=LOADSZ/256)
411 #endif
412 #endif
413 #ifdef USEA20BUFFER
414 movw $(LOADSZ+A20BUFFER)>>8, %di
415 #endif
416 popf
417 ja syslp
418 #ifdef INITRD_SUPPORT
419 initrdlp2:
420 #ifdef INITRD_AUTOADDR
421 movw $0x209, %cx
422 #else
423 movb $9, %cl
424 #endif
425 #ifdef MULTI_INITRD
426 movw $cur_initrd_size_ofs, %di
427 movw (%di), %bx
428 addw $4, (%di)
429 shrw %cl, boot_flag_ofs-cur_initrd_size_ofs(%di)
430 je nextInitrd
431 orw %bx, %bx
432 je bootit # no initrd
433 # ifdef INITRD_AUTOADDR
434 autoaddr cur_initrd_size_ofs(%di)
435 # endif
436 movw ramdisk_image+1,%ax
437 jmp initrdlp
438 nextInitrd:
439 pushw %bx
440 movl -4(%bx), %ebx
441 addl %ebx, ramdisk_size_ofs-cur_initrd_size_ofs(%di)
442 movb $swap_floppy2-0x100, %cs:dpy_swap_floppy-2+0x7C00
443 popw %bx
444 cmpb 2(%di), %bl
445 jb initrdlp
446 #else
447 movw $ramdisk_size, %bx
448 #ifdef MORETHAN16M
449 cmpb %cl, ramdisk_image+2-ramdisk_size(%bx)
450 jb bootit
451 # ifdef INITRD_AUTOADDR
452 autoaddr ramdisk_size_ofs(%bx)
453 # endif
454 movw ramdisk_image+1,%ax
455 shrw %cl, boot_flag-ramdisk_size(%bx)
456 jne initrdlp
457 #else
458 movw ramdisk_image+1,%ax
459 cmpw %ax, bootsect_dst_base+1(%si)
460 jb initrdlp
461 #endif
462 #endif
463 bootit:
464 #ifdef USEA20BUFFER
465 #ifdef MORETHAN16M
466 #ifdef INITRD_SUPPORT
467 movb %al, bootsect_dst_base_hi(%si) // assume @initrd 64k aligned
468 //movb $0, bootsect_dst_base_hi(%si)
469 #else
470 movb %cl, bootsect_dst_base_hi(%si)
471 #endif
472 #endif
473 movb $0x10, bootsect_dst_base+2(%si) // assume @initrd 64k aligned
474 //movw $0x1000, bootsect_dst_base+1(%si) // assume @initrd page aligned
475 movw $A20BUFFER/0x100, bootsect_src_base+1(%si)
476 movb $0x87, %ah
477 int $0x15
478 #endif
479 #endif
480 #ifdef MULTI_INITRD
481 jcxz read_sectorslp
482 #endif
484 # This procedure turns off the floppy drive motor, so
485 # that we enter the kernel in a known state, and
486 # don't have to worry about it later.
488 kill_motor:
489 #ifdef USEA20BUFFER
490 cwd
491 #else
492 xchgw %ax, %di # reset FDC (%di < 128)
493 #endif
494 int $0x13
496 # After that (everything loaded), we jump to the setup-routine
497 # loaded directly after the bootblock:
498 # Segments are as follows: %ds = %ss = INITSEG
500 ljmp $SETUPSEG, $0
502 # read_sectors reads %di sectors into %es:0 buffer.
503 # %es:0 is updated to the next memory location.
504 # First, sectors are read sector by sector until
505 # sector per track count is known. Then they are
506 # read track by track.
507 # Assume no error on first track.
509 #ifndef EXE_ONLY
511 #define FLOPPY_CYLINDERS 80
512 #define FLOPPY_HEADS 2
514 #if defined(MULTI_FLOPPY) && defined(COUNTER)
515 .macro putsmsg
516 movw $msgdigit+1-msg, %bx
517 nextdigit:
518 andb $0xF0, (%bx,%si)
519 decw %bx
520 incb (%bx,%si)
521 cmpb $'9', (%bx,%si)
522 ja nextdigit
523 call puts
524 .endm
525 #else
526 .macro putsmsg
527 call puts
528 .endm
529 #endif
531 check_limits:
532 popw %dx
533 cmpb %cl, %al # max sector known ?
534 jbe next_head # no -> store it
535 #.byte 0xd6 # SALC # sector by sector
536 movb $0, %al # sector by sector
537 pushaw
538 int $0x13 # reset controler
539 #ifndef NO_OUTPUT
540 stc
541 call putcdot # print '-'
542 #endif
543 read_sectorslp:
544 popaw
545 bdendlp:
546 pushw %dx # some bios break dx...
547 pushw %ax # limits
548 subb %cl, %al # sectors remaining in track
549 ja tolastsect
550 movb $1, %al # 1 sector mini
551 tolastsect:
552 cmpw %di, %ax
553 jb more1trk
554 movw %di, %ax # sectors to read
555 more1trk:
556 pushw %ax # save context
557 movb $2, %ah # cmd: read chs
558 int $0x13
559 popw %dx # save %ax
560 popw %ax # limits
561 jc check_limits
562 xchgw %ax, %bp
563 addw %dx,%cx # next sector
564 movw %cx, %gs
565 addb %dl,%bh
566 addb %dl,%bh # next location
567 subw %dx,%di # update sector counter
568 popw %dx
569 jz putcdot
570 read_sectors:
571 movw %gs, %cx
572 # al is last sector+1
573 # ah is 0
574 xchgw %ax, %bp
575 cmpb %al,%cl # reach sector limit ?
576 jne bdendlp
577 next_head:
578 movb %cl,%al
579 movb $1, %cl # first sector
580 inc_head:
581 xorb %cl, %dh # next head
582 jne bdendlp # reach head limit ?
583 incb %ch # next cylinder
584 read_first_sectors:
585 #ifndef MULTI_FLOPPY
586 jmp bdendlp
587 #else
588 cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
589 jne bdendlp
590 next_floppy:
591 movb $0,%ch # first cylinder
592 pushaw
593 movw $swap_floppy,%si
594 dpy_swap_floppy:
595 #ifdef KEYBOARDLESS_SUPPORT
596 pushw %bx
597 # ifndef NO_OUTPUT
598 putsmsg
599 # endif
600 popw %bx
601 movw %si, %bp
602 waitfloppy:
603 call wait
604 jne waitfloppydone
605 #ifdef MULTI_INITRD
606 decb (%si) # max_timeouts
607 gobootit:
608 //movw ramdisk_size+2-max_timeouts(%si), %cx
609 .byte 0x8B, 0x4C, ramdisk_size+2-max_timeouts
610 jz bootit
611 #endif
612 pushw %dx # some bios break dx...
613 cbw
614 int $0x13 # reset FDC
615 movw $0x201,%ax
616 int $0x13 # read first sector
617 popw %dx
618 rclb $1,%ah # floppy changed 06=>0D no error 00
619 cmpb -2(%bp), %ah # 0D then 00
620 jne waitfloppy # no => try again
621 incw %bp
622 decw %ax # was 0001 ?
623 jne waitfloppy
624 waitfloppydone:
625 #else
626 # ifndef NO_OUTPUT
627 putsmsg
628 # endif
629 cbw # %ah = 0, get keyboard character
630 int $0x16
631 #endif
632 #ifdef MULTI_INITRD
633 orb $0x20, %al
634 cmp $'b', %al
635 jz gobootit
636 #endif
637 jmp read_sectorslp
638 #endif
639 #endif
641 #ifdef EXE_SUPPORT
642 read_sectors_dos:
643 xorw %dx, %dx // write to %ds:%dx, not %es:%bx
644 call read_sectors_dosz
645 read_sectors_dosz:
646 pushw %es
647 popw %ds
648 movb $0x3F, %ah // read
649 movw %di, %cx
650 shlw $8, %cx // byte count / 2
651 movw %bp, %bx
652 int $0x21
653 xchgw %ax, %dx
654 pushw %ss
655 popw %ds
656 #endif
658 putcdot:
659 #ifndef NO_OUTPUT
660 movb $'.'+3, %al // . = success, - = failure
661 putclf:
662 sbbb $3, %al
663 putc:
664 movb $0xe, %ah
665 movw $7, %bx # one dot each 64k
666 int $0x10
667 cmp $0xd, %al # CR ?
668 je putclf
669 #endif
670 dosexit:
671 ret
673 #ifdef KEYBOARDLESS_SUPPORT
674 clock = 0x46C
675 wait:
676 wait4key:
677 movw $clock, %di
678 #define DELAY 5
679 movb $257-(DELAY*182)/10, %fs:(%di)
680 waitkbd:
681 movw $0x10D, %ax # test keyboard, timeout => CR
682 cmpb %fs:(%di),%ah
683 je waitdone
684 int $0x16
685 jz waitkbd
686 cbw
687 int $0x16 # eat char
688 movw %di, %fs # disable timeout
689 incw %di # clear Z
690 waitdone:
691 ret
692 #endif
694 #ifdef EXE_SUPPORT
695 comstart:
696 #ifndef EXE_ONLY
697 call initregs
698 #else
699 INIT_REGS
700 #endif
701 movb EXEADRS(setup_sects), %al # read bootsector + setup
702 incw %ax
703 #ifdef EXE_CMDLINE
704 movw $0x80, %si
705 movb (%si), %cl
706 incw %si
707 # if defined(OLDCMDLINE) && defined(FLOPPY_CMDLINE)
708 jcxz nocmdline
709 movw %di, EXEADRS(0x22)
710 movw $0xA33F, 0x7F(%si)
711 # endif
712 rep
713 movsb
714 nocmdline:
715 xchgw %ax, %di
716 # if defined(HELP) && defined(DISPLAY_VERSION)
717 cmpb $'?', -1(%si)
718 movw $EXEADRS(0x200), %si
719 je puts_version
720 # endif
721 #else
722 xchgw %ax, %di
723 #endif
724 #ifdef CHECK_REALMODE
725 smsww %ax
726 andb $1, %al
727 # if defined(HELP) && defined(DISPLAY_VERSION)
728 jne puts_version // real mode only...
729 # else
730 jne dosexit // real mode only...
731 # endif
732 movb $0x3D, %ah // open, access = RO
733 #else
734 movw $0x3D00, %ax // open, access = RO
735 #endif
736 movw 0x2C(%bx), %ds // DOS 3.0+
737 loop1:
738 incw %bx
739 cmpw %cx, (%bx)
740 jne loop1
741 leaw 4(%bx), %dx // %ds:%dx filename
742 int $0x21
743 jc dosexit
744 xchgw %ax, %bp // fd
745 call read_sectors_dos // update %ds
746 #ifndef EXE_ONLY
747 addb $read_sectors_dos-read_sectors, patchcall+1
748 #endif
749 #ifdef EXE_CMDLINE
750 # ifdef OLDCMDLINE
751 movw $0x202, %bx
752 cmpw %bx, 0x206-0x202(%bx) # new cmdline for version >= 0x202
753 jb oldcmdline
754 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx)
755 # else
756 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1
757 # endif
758 oldcmdline:
759 #endif
760 // ljmp $INITSEG, $loadsys
761 pushw %ds
762 .byte 0x6A, loadsys-bootsect_start # pushw $loadsys-bootsect_start
763 lretw
764 #endif
765 #define kernel_version_offset 0xE
766 #ifdef DISPLAY_VERSION
767 puts_version:
768 addw kernel_version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
769 #endif
770 #if defined(DISPLAY_VERSION) || defined(README_SUPPORT) || defined(FLOPPY_CMDLINE) || defined(MULTI_FLOPPY)
771 # ifndef NO_OUTPUT
772 puts:
773 movb $0xd, %al # CR
774 putcs:
775 call putc
776 lodsb
777 cmpb $0, %al # end of string is any byte <= 0
778 jg putcs
779 ret
780 # endif
781 #endif
783 #if defined(MULTI_FLOPPY) && !defined(EXE_ONLY)
784 initregs:
785 popw %si
786 INIT_REGS
787 pushw %si # use new stack
788 ret
789 #endif
792 #if defined(MULTI_FLOPPY) && !defined(EXE_SUPPORT)
793 #ifdef MULTI_INITRD
794 swap_floppy2:
795 .ascii "B or "
796 #endif
797 swap_floppy:
798 #ifdef COUNTER
799 msg:
800 .ascii "Put disk 00"
801 msgdigit:
802 .ascii "1, press Enter."
803 #else
804 .ascii "Next!"
805 #endif
806 .byte 7,13,0 # swap detection needs 13, 0
807 #ifdef MULTI_INITRD
808 max_timeouts:
809 .byte 20
810 table:
811 .org cur_initrd_size_ofs
812 cur_initrd_size:
813 .word table
814 .byte table+4-256
815 #endif
816 #endif
817 #ifdef README_SUPPORT
818 .org 0x1EF
819 readme:
820 .word 0
821 #endif
822 #ifdef LABEL
823 .ascii LABEL
824 #endif
825 .org 0x1F1
827 #ifdef MULTI_INITRD
828 .org 0x400
830 orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
831 pushal
833 movw $10+16, %cx
834 fillbuf:
835 pushw $0
836 loop fillbuf
837 popal // clear regiters
838 maploop:
839 movw %sp, %di // %es = %ss
840 movb $20, %cl
841 movw $0xE820, %ax
842 movl $0x534d4150, %edx
843 int $0x15
844 sbbl %eax, %edx
845 jne mapdone
846 decw 16(%di)
847 jne notram
848 addw 8+2(%di), %bp
849 notram:
850 orw %bx, %bx
851 jnz maploop
852 mapdone:
853 addw $20, %sp
854 shrw $20-16,%bp
855 jnz mapdone2
856 movb $0x88, %ah
857 int $0x15
858 xchgw %ax, %bp
859 shrw $10, %bp
860 mapdone2:
861 incw %bp
862 // %bp : nb Mb
863 call here
864 here:
865 popw %di
866 movw $0x1EE, %si
867 lodsw
868 sizeloop:
869 scasw // %di += 2
870 addw $4, %ax
871 cmpb %al, (%si)
872 jbe sizedone
873 cmpw %bp, sizes-here(%di)
874 jbe sizeloop
875 movb %al, (%si)
876 sizedone:
877 popal
878 lret // need %si
879 sizes:
881 #endif