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

Fix ctorrent-dnh & tfttest
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Jul 14 09:04:04 2021 +0000 (2021-07-14)
parents 063403f23e53
children
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 //.arch i386,nojumps
51 .code16
52 .org 0
54 #ifdef NO_OUTPUT
55 # undef DISPLAY_VERSION
56 # undef README_SUPPORT
57 # undef FLOPPY_CMDLINE
58 # undef COUNTER
59 #endif
61 bootsect_start:
63 cur_initrd_size_ofs = 494
64 ramdisk_image_ofs = 0x218
65 ramdisk_image = bootsect_start+ramdisk_image_ofs
66 ramdisk_size_ofs = 0x21C
67 ramdisk_size = bootsect_start+ramdisk_size_ofs
68 cmd_line_ptr_ofs = 0x228
69 cmd_line_ptr = bootsect_start+cmd_line_ptr_ofs
70 setup_sects = bootsect_start+497
71 syssize = bootsect_start+500
72 boot_flag_ofs = 510
73 boot_flag = bootsect_start+boot_flag_ofs
76 stacktop = 0x9E00 # in 0x8000 .. 0xA000
77 #ifdef NO_FLOPPY_TABLE_PATCH
78 zeroed = 48+8 # gdt + zeroed registers
79 #else
80 zeroed = 48+10 # gdt + zeroed registers
81 #endif
82 .macro INIT_REGS
83 movw $stacktop-zeroed, %di # stacktop is an arbitrary value >=
84 # length of bootsect + length of
85 # setup + room for stack;
86 # 12 is disk parm size.
87 movw $INITSEG, %ax
88 movw %ax, %ss # %ss contain INITSEG
89 movw %di, %sp # put stack at INITSEG:stacktop-...
90 movw %ax, %es # %es = %ss = INITSEG
91 cbw # %ax = 0
92 cld
93 #ifdef EXE_CMDLINE
94 movw $zeroed+1, %cx # clear gdt + offset, %ds, limits, cmdline=""
95 rep
96 stosb
97 decw %di
98 #else
99 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
100 rep
101 stosw
102 #endif
103 popw %bx # offset = 0
104 .endm
106 #ifdef FAT12_SUPPORT
107 jmp fdstart
108 nop
109 .ascii "SLITAZ "
110 .word 512 // 0B: bytes per sector
111 .byte 1 // 0D: sectors per cluster
112 .word 2880 // 0E: reserved seectors
113 .byte 2 // 10: FAT number
114 .word 64 // 11: root entries 4x 16
115 .word 2880 // 13: total sectors
116 .byte 0xF0 // 15: media id (or F9)
117 #endif
119 #ifdef EXE_SUPPORT
120 #define CODESZ 0x8000
121 #define EXEADRS(x) x+0xE0
122 decw %bp // Magic number: MZ
123 popw %dx
124 #ifdef EXE_ONLY
125 .word 512 // Bytes on last page of file
126 #else
127 jmp fdstart // Bytes on last page of file
128 #endif
129 .word (CODESZ+511)/512 // Pages in file
130 .word 0 // Relocations
131 .word 2 // Size of header in paragraphs
132 .word 4096 // Minimum extra paragraphs needed
133 .word -1 // Maximum extra paragraphs needed
134 .word (CODESZ+15)/16 // Initial (relative) SS value
135 .word stacktop+4 // Initial SP value (+callf)
136 .word 0 // Checksum
137 .word EXEADRS(comstart) // Initial IP value
138 .word 0xFFF0 // Initial (relative) CS value
139 #if defined(EXE_ONLY) || !defined(MULTI_FLOPPY) || defined(COUNTER)
140 // .word 0x001C // File address of relocation table
141 // .word 0,0,0 // Overlay number
142 .ascii "(SliTaz)"
143 #else
144 swap_floppy:
145 .ascii "Next!"
146 .byte 7,13,0 # swap detection needs 13, 0
147 #endif
148 #ifdef OLDCMDLINE
149 # ifdef FLOPPY_CMDLINE
150 .word 0 # 0xA33F
151 .word 0 # stacktop
152 # else
153 .word 0xA33F
154 .word stacktop
155 # endif
156 #endif
157 #ifndef EXE_ONLY
158 fdstart:
159 pushw %dx
160 #endif
161 #endif
163 LOADSEG = 0x8000 # 0x1000 multiple, up to 512K zImage
164 LOADSZ = 0x10000
166 #if defined(EXE_SUPPORT) || defined(EXE_ONLY)
167 A20BUFFER = 0x68000 # a20 gate / himem.sys support
168 #define USEA20BUFFER # Does not break zImage support
169 #endif
171 #ifndef EXE_ONLY
172 # bootsect_start:
173 #ifdef EXE_SUPPORT
174 call initregs
175 cwd # floppy = head = 0
176 #else
177 INIT_REGS
178 #endif
179 popw %ds # %ds = 0
180 movb setup_sects+0x7C00, %al # read bootsector + setup
181 incw %ax # %ax = setup_sects+bootsect
182 popw %fs # %fs = 0
184 # Many BIOS's default disk parameter tables will not recognize
185 # multi-sector reads beyond the maximum sector number specified
186 # in the default diskette parameter tables - this may mean 7
187 # sectors in some cases.
188 #
189 # Since single sector reads are slow and out of the question,
190 # we must take care of this by creating new parameter tables
191 # (for the first disk) in RAM. We can set the maximum sector
192 # count to 36 - the most we will encounter on an ED 2.88.
193 #
194 # High doesn't hurt. Low does. Let's use the max: 63
196 cli
197 #ifdef NO_FLOPPY_TABLE_PATCH
198 xchg %ax, %di # sector count
199 popw %ax # limits = 0
200 incw %cx # cylinder 0, sector 1, clear Z
201 call read_first_sectors # read setup
202 # ifdef FLOPPY_CMDLINE
203 movw $0, %si # patched by installer (7C22)
204 skipcmdline:
205 #define cmd_line_ptr 0x22
206 # endif
207 #else
208 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
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 # 720KB 800KB 880KB 1.04MB 1.12MB 1.2MB 1.44MB 1.6MB 1.68MB 1.76MB
512 # 1.84MB 1.92MB 2.88MB 3.12MB 3.20MB 3.52MB 3.84MB support
513 # do not support 820KB 830KB 1.48MB 1.49MB 1.72MB 1.74MB
514 #define FLOPPY_CYLINDERS 80
515 # do not support 360KB 410KB 420KB
516 #define FLOPPY_HEADS 2
518 #if defined(MULTI_FLOPPY) && defined(COUNTER)
519 .macro putsmsg
520 movw $msgdigit+1-msg, %bx
521 nextdigit:
522 andb $0xF0, (%bx,%si)
523 decw %bx
524 incb (%bx,%si)
525 cmpb $'9', (%bx,%si)
526 ja nextdigit
527 call puts
528 .endm
529 #else
530 .macro putsmsg
531 call puts
532 .endm
533 #endif
535 check_limits:
536 cmpb %cl, %al # max sector known ?
537 jbe next_head # no -> store it
538 #.byte 0xd6 # SALC # sector by sector
539 movb $0, %al # sector by sector
540 pushaw
541 int $0x13 # reset controler
542 #ifndef NO_OUTPUT
543 stc
544 call putcdot # print '-'
545 #endif
546 read_sectorslp:
547 popaw
548 bdendlp:
549 pushw %dx # some bios break dx...
550 pushw %ax # limits
551 subb %cl, %al # sectors remaining in track
552 ja tolastsect
553 movb $1, %al # 1 sector mini
554 tolastsect:
555 cmpw %di, %ax
556 jb more1trk
557 movw %di, %ax # sectors to read
558 more1trk:
559 pushw %ax # save context
560 movb $2, %ah # cmd: read chs
561 int $0x13
562 popw %bp # save %ax
563 popw %ax # limits
564 popw %dx
565 jc check_limits
566 xchgw %ax, %bp
567 addw %ax,%cx # next sector
568 movw %cx, %gs
569 addb %al,%bh
570 addb %al,%bh # next location
571 subw %ax,%di # update sector counter
572 jz putcdot
573 read_sectors:
574 movw %gs, %cx
575 # al is last sector+1
576 # ah is 0
577 xchgw %ax, %bp
578 cmpb %al,%cl # reach sector limit ?
579 jne bdendlp
580 next_head:
581 movb %cl,%al
582 movb $1, %cl # first sector
583 inc_head:
584 xorb %cl, %dh # next head
585 jne bdendlp # reach head limit ?
586 incb %ch # next cylinder
587 read_first_sectors:
588 #ifndef MULTI_FLOPPY
589 jmp bdendlp
590 #else
591 cmpb $FLOPPY_CYLINDERS,%ch # reach cylinder limit ?
592 jne bdendlp
593 next_floppy:
594 movb $0,%ch # first cylinder
595 pushaw
596 movw $swap_floppy,%si
597 dpy_swap_floppy:
598 #ifdef KEYBOARDLESS_SUPPORT
599 pushw %bx
600 # ifndef NO_OUTPUT
601 putsmsg
602 # endif
603 popw %bx
604 movw %si, %bp
605 waitfloppy:
606 call wait
607 jne waitfloppydone
608 #ifdef MULTI_INITRD
609 decb (%si) # max_timeouts
610 gobootit:
611 //movw ramdisk_size+2-max_timeouts(%si), %cx
612 .byte 0x8B, 0x4C, ramdisk_size+2-max_timeouts
613 jz bootit
614 #endif
615 pushw %dx # some bios break dx...
616 cbw
617 int $0x13 # reset FDC
618 movw $0x201,%ax
619 int $0x13 # read first sector
620 popw %dx
621 rclb $1,%ah # floppy changed 06=>0D no error 00
622 cmpb -2(%bp), %ah # 0D then 00
623 jne waitfloppy # no => try again
624 incw %bp
625 decw %ax # was 0001 ?
626 jne waitfloppy
627 waitfloppydone:
628 #else
629 # ifndef NO_OUTPUT
630 putsmsg
631 # endif
632 cbw # %ah = 0, get keyboard character
633 int $0x16
634 #endif
635 #ifdef MULTI_INITRD
636 orb $0x20, %al
637 cmp $'b', %al
638 jz gobootit
639 #endif
640 jmp read_sectorslp
641 #endif
642 #endif
644 #ifdef EXE_SUPPORT
645 read_sectors_dos:
646 xorw %dx, %dx // write to %ds:%dx, not %es:%bx
647 call read_sectors_dosz
648 read_sectors_dosz:
649 pushw %es
650 popw %ds
651 movb $0x3F, %ah // read
652 movw %di, %cx
653 shlw $8, %cx // byte count / 2
654 movw %bp, %bx
655 int $0x21
656 xchgw %ax, %dx
657 pushw %ss
658 popw %ds
659 #endif
661 putcdot:
662 #ifndef NO_OUTPUT
663 movb $'.'+3, %al // . = success, - = failure
664 putclf:
665 sbbb $3, %al
666 putc:
667 movb $0xe, %ah
668 movw $7, %bx # one dot each 64k
669 int $0x10
670 cmp $0xd, %al # CR ?
671 je putclf
672 #endif
673 dosexit:
674 ret
676 #ifdef KEYBOARDLESS_SUPPORT
677 clock = 0x46C
678 wait:
679 wait4key:
680 movw $clock, %di
681 #define DELAY 5
682 movb $257-(DELAY*182)/10, %fs:(%di)
683 waitkbd:
684 movw $0x10D, %ax # test keyboard, timeout => CR
685 cmpb %fs:(%di),%ah
686 je waitdone
687 int $0x16
688 jz waitkbd
689 cbw
690 int $0x16 # eat char
691 movw %di, %fs # disable timeout
692 incw %di # clear Z
693 waitdone:
694 ret
695 #endif
697 #ifdef EXE_SUPPORT
698 comstart:
699 #ifndef EXE_ONLY
700 call initregs
701 #else
702 INIT_REGS
703 #endif
704 movb EXEADRS(setup_sects), %al # read bootsector + setup
705 incw %ax
706 #ifdef EXE_CMDLINE
707 movw $0x80, %si
708 movb (%si), %cl
709 incw %si
710 # if defined(OLDCMDLINE) && defined(FLOPPY_CMDLINE)
711 jcxz nocmdline
712 movw %di, EXEADRS(0x22)
713 movw $0xA33F, 0x7F(%si)
714 # endif
715 rep
716 movsb
717 nocmdline:
718 xchgw %ax, %di
719 # if defined(HELP) && defined(DISPLAY_VERSION)
720 cmpb $'?', -1(%si)
721 movw $EXEADRS(0x200), %si
722 je puts_version
723 # endif
724 #else
725 xchgw %ax, %di
726 #endif
727 #ifdef CHECK_REALMODE
728 smsww %ax
729 andb $1, %al
730 # if defined(HELP) && defined(DISPLAY_VERSION)
731 jne puts_version // real mode only...
732 # else
733 jne dosexit // real mode only...
734 # endif
735 movb $0x3D, %ah // open, access = RO
736 #else
737 movw $0x3D00, %ax // open, access = RO
738 #endif
739 movw 0x2C(%bx), %ds // DOS 3.0+
740 loop1:
741 incw %bx
742 cmpw %cx, (%bx)
743 jne loop1
744 leaw 4(%bx), %dx // %ds:%dx filename
745 int $0x21
746 jc dosexit
747 xchgw %ax, %bp // fd
748 call read_sectors_dos // update %ds
749 #ifndef EXE_ONLY
750 addb $read_sectors_dos-read_sectors, patchcall+1
751 #endif
752 #ifdef EXE_CMDLINE
753 # ifdef OLDCMDLINE
754 movw $0x202, %bx
755 cmpw %bx, 0x206-0x202(%bx) # new cmdline for version >= 0x202
756 jb oldcmdline
757 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1-0x202(%bx)
758 # else
759 movw $INITSEG/16+stacktop/256, cmd_line_ptr+1
760 # endif
761 oldcmdline:
762 #endif
763 // ljmp $INITSEG, $loadsys
764 pushw %ds
765 .byte 0x6A, loadsys-bootsect_start # pushw $loadsys-bootsect_start
766 lretw
767 #endif
768 #define kernel_version_offset 0xE
769 #ifdef DISPLAY_VERSION
770 puts_version:
771 addw kernel_version_offset(%si),%si # starting protocol 2.00, Kernel 1.3.73
772 #endif
773 #if defined(DISPLAY_VERSION) || defined(README_SUPPORT) || defined(FLOPPY_CMDLINE) || defined(MULTI_FLOPPY)
774 # ifndef NO_OUTPUT
775 puts:
776 movb $0xd, %al # CR
777 putcs:
778 call putc
779 lodsb
780 cmpb $0, %al # end of string is any byte <= 0
781 jg putcs
782 ret
783 # endif
784 #endif
786 #if defined(MULTI_FLOPPY) && !defined(EXE_ONLY)
787 initregs:
788 popw %si
789 INIT_REGS
790 pushw %si # use new stack
791 ret
792 #endif
795 #if defined(MULTI_FLOPPY) && !defined(EXE_SUPPORT)
796 #ifdef MULTI_INITRD
797 swap_floppy2:
798 .ascii "B or "
799 #endif
800 swap_floppy:
801 #ifdef COUNTER
802 msg:
803 .ascii "Put disk 00"
804 msgdigit:
805 .ascii "1, press Enter."
806 #else
807 .ascii "Next!"
808 #endif
809 .byte 7,13,0 # swap detection needs 13, 0
810 #ifdef MULTI_INITRD
811 max_timeouts:
812 .byte 20
813 table:
814 .org cur_initrd_size_ofs
815 cur_initrd_size:
816 .word table
817 .byte table+4-256
818 #endif
819 #endif
820 #ifdef README_SUPPORT
821 .org 0x1EF
822 readme:
823 .word 0
824 #endif
825 #ifdef LABEL
826 .ascii LABEL
827 #endif
828 .org 0x1F1
830 #ifdef MULTI_INITRD
831 .org 0x400
833 orw $0x8020, type_of_loader(%si) # loader type = 0x20 = bootsect-loader
834 pushal
836 movw $10+16, %cx
837 fillbuf:
838 pushw $0
839 loop fillbuf
840 popal // clear regiters
841 maploop:
842 movw %sp, %di // %es = %ss
843 movb $20, %cl
844 movw $0xE820, %ax
845 movl $0x534d4150, %edx
846 int $0x15
847 sbbl %eax, %edx
848 jne mapdone
849 decw 16(%di)
850 jne notram
851 addw 8+2(%di), %bp
852 notram:
853 orw %bx, %bx
854 jnz maploop
855 mapdone:
856 addw $20, %sp
857 shrw $20-16,%bp
858 jnz mapdone2
859 movb $0x88, %ah
860 int $0x15
861 xchgw %ax, %bp
862 shrw $10, %bp
863 mapdone2:
864 incw %bp
865 // %bp : nb Mb
866 call here
867 here:
868 popw %di
869 movw $0x1EE, %si
870 lodsw
871 sizeloop:
872 scasw // %di += 2
873 addw $4, %ax
874 cmpb %al, (%si)
875 jbe sizedone
876 cmpw %bp, sizes-here(%di)
877 jbe sizeloop
878 movb %al, (%si)
879 sizedone:
880 popal
881 lret // need %si
882 sizes:
884 #endif