wok view linld/stuff/src/CRTL.ASM @ rev 20484

linld: ipxe does not respect realmode_switch protocol
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Oct 21 17:30:30 2018 +0200 (2018-10-21)
parents 623f02d7e6c8
children f5088c165f51
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %crefref
6 %noincl
7 %nomacs
8 ifdef NO386
9 p8086
10 else
11 p386
12 endif
14 group DGROUP _TEXT,_DATA,_BSS
15 assume cs:DGROUP,ds:DGROUP
17 segment _DATA byte public use16 'DATA'
19 global _heap_top
20 extrn _bss_end
21 _heap_top dw _bss_end
22 msg_hang db "High mem corrupted - not exiting to DOS"
23 msg_crlf db 13,10,0
24 vcpi_alloc_err db "VCPI "
25 msg_malloc db "malloc error",0
26 ifdef EXTRA
27 tazboot_cmd db "tazboot.cmd",0
28 endif
30 ends _DATA
32 segment _BSS byte public use16 'BSS'
34 global _no_exit:byte
35 _no_exit db ?
36 filecnt db ? ; in fact 0 minus file count...
37 nextfilename dw ?
38 ifdef LARGE_IMAGES
39 curdata dw ?
40 endif
41 ifdef EXTRA
42 ultoabuf db 12 dup (?)
43 endif
45 ends _BSS
47 segment _TEXT byte public use16 'CODE'
49 ;***************************************************************
50 ;char* strcpy(const char* a, const char* b);
51 ;char* strcat(const char* a, const char* b);
52 ;char* strcatb(const char* a, const char* b);
53 ;***************************************************************
54 global _strcatb:near
55 proc _strcatb near
57 ifdef EXTRA
58 mov cl,7Fh
59 db 0bbh ; mov bx,imm opcode
60 global _strcat:near
61 _strcat:
62 mov cl,80h
63 db 0bbh ; mov bx,imm opcode
64 global _strcpy:near
65 _strcpy:
66 xor cx,cx
67 endif
68 pop ax ;caller return address
69 pop dx ; a
70 pop bx ; b
71 push bx
72 push dx
73 push ax
74 push si
75 mov si,dx
76 ifdef EXTRA
77 jcxz @@nocat
78 endif
79 @@catlp:
80 lodsb
81 cmp al,0
82 jne @@catlp
83 dec si
84 ifdef EXTRA
85 cmp dx,si
86 adc al,cl ; set S when dx != si or cl = 80
87 mov al,20h
88 jns @@cpyhead
89 endif
90 @@nocat:
91 @@cpylp:
92 mov al,[bx]
93 inc bx
94 @@cpyhead:
95 mov [si],al
96 inc si
97 cmp al,0
98 jne @@cpylp
99 strfound:
100 xchg ax,dx
101 strend:
102 pop si
103 ret
105 endp _strcatb
108 ifdef EXTRA
109 p8086
110 ;***************************************************************
111 ;char strstr(const char* a,const char* b);
112 ;***************************************************************
113 global _strstr:near
114 proc _strstr near
116 pop ax ;caller return address
117 pop dx ; a
118 pop cx ; b
119 push cx
120 push dx
121 push ax
122 push si
123 @@loop:
124 xor ax,ax
125 mov si,dx
126 cmp [si],al ; *a
127 jz strend ; return ax = NULL
128 mov bx,cx
129 @@match:
130 or ah,[bx] ; *b
131 jz strfound
132 inc bx
133 lodsb
134 sub ah,al
135 jz @@match
136 inc dx
137 jmp @@loop
139 endp _strstr
142 ;***************************************************************
143 ;int strcmp(const char* a,const char* b);
144 ;***************************************************************
145 global _strcmp:near
146 proc _strcmp near
148 pop cx ;caller return address
149 pop bx ; a
150 pop ax ; b
151 push ax
152 push bx
153 push cx
154 push si
155 xchg ax,si
156 dec bx
157 @@lp:
158 inc bx
159 lodsb
160 sub al,[bx]
161 jnz @@out
162 sub al,al
163 jnz @@lp
164 @@out:
165 cbw
166 pop si
167 ret
169 endp _strcmp
170 endif
173 ;***************************************************************
174 ;void puts(const char* s):
175 ;***************************************************************
176 global _puts:near
177 proc _puts near
179 pop ax ;caller return address
180 pop bx ; s
181 push bx
182 push ax
183 global puts:near ; puts(bx)
184 puts:
185 call putsz
186 mov bx,offset msg_crlf
187 jmp putsz
188 putcz:
189 mov ah,2
190 int 21h
191 global putsz:near ; putsz(bx)
192 putsz:
193 mov dl,[bx]
194 inc bx
195 or dl,dl
196 jne putcz ; ZF=1 (for malloc failure)
197 ret
199 endp _puts
202 ;***************************************************************
203 ;int fileattr(const char* name);
204 ;***************************************************************
205 global _fileattr:near
206 proc _fileattr near
208 pop ax ;caller return address
209 pop dx ; name
210 push dx
211 push ax
212 mov ax,4300h
213 int 21h
214 xchg ax,cx
215 jmp chkc
217 endp _fileattr
220 ;***************************************************************
221 ;int open(const char* name, int flags=O_RDONLY);
222 ;***************************************************************
223 global _open:near
224 proc _open near
226 pop ax ;caller return address
227 pop bx ; name
228 push bx
229 push ax
230 global open:near ; open(bx)
231 open:
232 mov dx,bx
233 ;mov cl,0 ; attribute mask
234 mov ax,3d00h ; read-only+compatibility
235 dos:
236 int 21h
237 chkc:
238 jnc doret
239 fail:
240 sbb ax,ax ; ax=-1 CF
241 cwd
242 doret:
243 ifndef NO386
244 push dx ; see next_chunk:lseek
245 push ax
246 pop eax
247 endif
248 ret
250 endp _open
253 ;***************************************************************
254 ;int close(int fd);
255 ;***************************************************************
256 global _close:near
257 proc _close near
259 pop ax ;caller return address
260 pop bx ; fd
261 push bx
262 push ax
263 global close:near ; close(bx)
264 close:
265 mov ah,3Eh
266 or bx,bx
267 jnz dos
268 ret
270 endp _close
273 ;***************************************************************
274 ;int read(int fd, void* data, int sz);
275 ;int write(int fd, const void* data, int sz);
276 ;***************************************************************
277 global _read:near
278 proc _read near
280 ifdef WRITE
281 stc
282 db 0B0h ; mov al,im
283 global _write:near
284 clc
285 endif
286 pop ax ;caller return address
287 pop bx ; fd
288 pop dx ; data
289 pop cx ; sz
290 push cx
291 push dx
292 push bx
293 push ax
294 ifdef WRITE
295 mov ah,40h
296 sbb ah,0
297 else
298 mov ah,3Fh
299 endif
300 jcxz fail
301 jmp dos
303 endp _read
305 proc _lseekset near
306 ;ifdef EXTRA
307 ;***************************************************************
308 ;long lseekset(int fd, unsigned long sz);
309 ;***************************************************************
311 global _lseekset:near
313 pop ax ;caller return address
314 pop bx ; fd
315 pop dx ; sz lo
316 pop cx ; sz hi
317 push cx
318 push dx
319 push bx
320 push ax
321 ;endif
322 global lseekset:near
323 lseekset:
324 clc
325 db 0B0h ; mov al,im
326 global rewind:near
327 rewind: ; rewind(bx)
328 stc
329 mov ax,4200h
330 jnc dos
331 lseek0: ; lseek0(bx,ax=dir)
332 cwd
333 xor cx,cx
334 jmp dos
336 endp _lseekset
338 ifdef EXTRA
339 struc isostate ; struct isostate {
340 fd dw ? ; 0 int fd;
341 fileofs dd ? ; 2 unsigned long fileofs;
342 filesize dd ? ; 6 unsigned long filesize;
343 filemod dw ? ;10 unsigned short filemod;
344 filename dw ? ;12 char *filename;
345 dirofs dd ? ;14 unsigned long dirofs;
346 dirsize dd ? ;16 unsigned long dirsize;
347 curdirofs dd ? ;20 unsigned long curdirofs;
348 curdirsize dd ? ;24 unsigned long curdirsize;
349 curpos dd ? ;28 unsigned long curpos;
350 ends ; } isostate;
351 ;***************************************************************
352 ;unsigned long isolseek(const unsigned long *offset);
353 ;***************************************************************
354 global _isolseek:near
355 proc _isolseek near
357 pop ax
358 pop bx
359 push bx
360 push ax
361 mov dx,[bx]
362 mov cx,[bx+2]
363 extrn _isostate:isostate
364 mov bx,[_isostate.fd]
365 jmp lseekset ; (bx=fd, sz=cx:dx)
367 endp _isolseek
368 endif
371 ;***************************************************************
372 ;int strhead(const char* a,const char* b);
373 ;***************************************************************
374 global _strhead:near
375 proc _strhead near
377 pop cx ;caller return address
378 pop bx ; a
379 pop ax ; b
380 push ax
381 push bx
382 push cx
383 @@loop:
384 xchg ax,bx
385 mov cl,[bx] ; cl = *b++
386 inc bx
387 or cl,cl ; clear C
388 jz fail ; return 0
389 xchg ax,bx
390 xor cl,[bx] ; cl -= *a++
391 inc bx
392 and cl,0dfh ; case insensitive
393 jz @@loop
394 ret ; return b (is not 0)
396 endp _strhead
399 ;***************************************************************
400 ;char* malloc_or_die(unsigned size);
401 ;***************************************************************
402 global _malloc_or_die:near
403 proc _malloc_or_die near
405 pop ax ;caller return address
406 pop cx ; size
407 push cx
408 push ax
409 global malloc_or_die:near ; malloc_or_die(cx)
410 malloc_or_die:
411 mov ax,[_heap_top] ; return value
412 mov bx,sp
413 add bh,-14h ; MIN_STACK=_1k+PAGE_SIZE
414 sub bx,ax ; can't overflow
415 cmp bx,cx
416 mov bx,offset msg_malloc
417 jb die
418 add [_heap_top],cx ; _BEG has zero'd heap
419 ret
421 endp _malloc_or_die
424 ;***************************************************************
425 ;int die(const char* msg);
426 ;int exit();
427 ;int abort();
428 ;***************************************************************
429 global _die:near
430 proc _die near
432 pop ax ;caller return address
433 pop bx ; s
434 push bx
435 push ax
436 global die:near ; die(bx)
437 die:
438 call puts
439 global _exit:near
440 _exit:
441 mov al,[_no_exit]
442 cmp al,0
443 jne @@hang
444 extrn exit:near
445 inc ax
446 jmp near exit
447 @@hang:
448 mov bx, offset msg_hang
449 call puts
450 global _abort:near
451 _abort:
452 cli
453 @@stop:
454 hlt
455 jmp @@stop
457 endp _die
459 struc image_himem ;struct image_himem {
460 fd dw ? ; 0 int fd;
461 fallback dd ? ; 2 u32 fallback;
462 size dd ? ; 6 u32 size;
463 remaining dd ? ;10 u32 remaining;
464 buf dd ? ;14 u32 buf;
465 bufv dw ? ;18 u32 *bufv;
466 errmsg dw ? ;20 char *errmsg;
467 chunk_size dd ? ;22 u32 chunk_size;
468 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
469 state dw ? ;28 u16 state;
470 fd2close dw ? ;30 u16 fd2close;
471 ends ;};
473 ;***************************************************************
474 ;long next_chunk(struct image_himem *di);
475 ;***************************************************************
476 proc next_chunk near
478 push si
479 mov bx,[(image_himem di).fd]
480 call close
481 ifndef NO386
482 xor eax,eax
483 else
484 xor ax,ax
485 endif
486 cwd
487 mov [(image_himem di).fd],ax
488 mov bx,[(image_himem di).state]
489 cmp al,[bx] ; ""
490 jz @@end
491 mov si,bx
492 @@scan:
493 lodsb
494 mov cx,si
495 cmp al,','
496 jz @@eos
497 cmp al,0
498 jnz @@scan
499 dec cx
500 @@eos:
501 mov [(image_himem di).state],cx
502 dec si
503 push [word si]
504 mov [byte si],dl ; set temp eos
505 call open
506 pop [word si] ; restore string
507 jc @@die
508 mov [(image_himem di).fd],ax
509 mov [(image_himem di).fd2close],ax
510 xchg ax,bx
511 mov ax,4202h ; SEEK_END
512 call lseek0
513 @@die:
514 mov bx,[(image_himem di).errmsg]
515 jc die
516 mov bx,[(image_himem di).fd]
517 ifndef NO386
518 push eax
519 call rewind
520 pop eax
521 @@end:
522 mov [(image_himem di).chunk_size],eax
523 else
524 push ax
525 push dx
526 call rewind
527 pop dx
528 pop ax
529 @@end:
530 mov [word (image_himem di).chunk_size],ax
531 mov [word ((image_himem di).chunk_size)+2],dx
532 endif
533 pop si
534 ret
536 endp next_chunk
539 ifdef LARGE_IMAGES
540 struc data_himem ;struct data_himem {
541 first dd ? ; 0 u32 first;
542 cacheidx dw ? ; 4 int cacheidx;
543 pageidx dw ? ; 6 int pageidx;
544 cache dd 1024 dup(?) ; 8 int cache;
545 page dd 1024 dup(?) ;4104 int page;
546 ends ;}; // size=8200
547 endif
549 ;***************************************************************
550 ;u32* malloc_bufv_or_die(struct image_himem *m);
551 ;***************************************************************
552 global _malloc_bufv_or_die:near
553 proc _malloc_bufv_or_die near
555 p386
556 pop bx ;caller return address
557 pop ax
558 push ax
559 push bx
560 push si
561 xchg ax,si
562 ifdef LARGE_IMAGES
563 mov cx,[word ((image_himem si).size) + 2]
564 shr cx,4 ; pages index size = size >> 20
565 add cx,8+4096+8
566 call malloc_or_die
567 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
568 add ecx,[(image_himem si).size]
569 shr ecx,12
570 mov [curdata],ax
571 else
572 mov ecx,[(image_himem si).size]
573 dec ecx
574 shr ecx,12
575 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
576 push cx
577 inc cx ; cnt+1
578 shl cx,2 ; bufv => vcpi => vm86
579 ; our malloc zeroes allocated mem: bufv[cnt]=0;
580 ; Allocate pages, storing addrs in addrbuf
581 call malloc_or_die
582 pop cx
583 push ax
584 endif
585 mov [(image_himem si).bufv],ax
586 xchg ax,si
587 @@vcpi_alloc:
588 xor edx,edx
589 mov ax,0DE04h
590 int 67h
591 or ah,ah
592 mov bx,offset vcpi_alloc_err
593 jnz die
594 ; for (i = cnt-1; i >= 0; i--)
595 ifdef LARGE_IMAGES
596 mov eax,ecx
597 dec eax
598 else
599 mov ax,cx
600 dec ax
601 cwde
602 endif
603 shl eax,12 ; i*_4k
604 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
605 extrn _imgs
606 mov bx,offset _imgs+2
607 push eax
608 add eax,[bx-2+2]
609 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
610 pop eax ; i*_4k
611 jbe @@pmok
612 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
613 jae @@vcpi_alloc
614 @@pmok:
615 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
616 extrn _imgs
617 mov bx,offset _imgs+32+2
618 add eax,[bx-2+2] ; +initrd.fallback
619 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
620 ja @@initrdok
621 mov eax,[bx-2+6] ; initrd.size
622 add eax,[bx-2+2] ; +initrd.fallback
623 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
624 @@jnc_vcpi_alloc:
625 ja @@vcpi_alloc
626 @@initrdok:
627 ifdef LARGE_IMAGES
628 cmp [(data_himem si).first],0
629 jne @@notfirst
630 mov [(data_himem si).first],edx
631 @@notfirst:
632 mov bx,[(data_himem si).cacheidx]
633 cmp bh,4
634 jae @@nextpage
635 shl bx,2
636 inc [(data_himem si).cacheidx]
637 mov [(data_himem bx+si).cache],edx
638 loopd @@vcpi_alloc
639 mov [(data_himem bx+si).cache],ecx ; last is 0
640 @@nextpage:
641 and [(data_himem si).cacheidx],0
642 mov bx,[(data_himem si).pageidx]
643 mov [(data_himem bx+si).page],edx
644 add [(data_himem si).pageidx],4
645 push cx
646 lea cx,[(data_himem si).cache]
647 ifdef NO386
648 push edx
649 pop dx
650 pop ax
651 endif
652 call storepage ; storepage(edx,cx)
653 pop cx
654 or ecx,ecx ; clear C
655 jnz @@jnc_vcpi_alloc
656 mov [dword (data_himem si).cacheidx],ecx
657 xchg ax,si
658 else
659 mov [si],edx
660 lodsd ; si=+4
661 loop @@vcpi_alloc
662 pop ax
663 endif
664 pop si
665 ret
666 ifdef NO386
667 p8086
668 endif
670 endp _malloc_bufv_or_die
673 ;***************************************************************
674 ; void memcpy_image(struct image_himem *m);
675 ;***************************************************************
676 global _memcpy_image:near
677 proc _memcpy_image near
679 pop ax ;caller return address
680 pop bx
681 push bx
682 push ax
683 ifndef NO386
684 mov edx,[(image_himem bx).fallback]
685 mov eax,[(image_himem bx).buf]
686 cmp eax,edx ; if (m->fallback != m->buf)
687 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
688 ifdef LARGE_IMAGES
689 mov ecx,[(image_himem bx).size]
690 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
691 push ecx
692 else
693 push [(image_himem bx).size]
694 endif
695 push eax
696 push 0
697 call_memcpy32:
698 push edx
699 else
700 mov ax,[word ((image_himem bx).fallback)]
701 mov dx,[word ((image_himem bx).fallback)+2]
702 mov cx,[word ((image_himem bx).buf)]
703 cmp ax,cx ; if (m->fallback != m->buf)
704 jnz @@do
705 cmp dx,[word ((image_himem bx).buf)+2]
706 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
707 @@do:
708 push [word ((image_himem bx).size)+2]
709 push [word ((image_himem bx).size)]
710 push [word ((image_himem bx).buf)+2]
711 push cx
712 xor cx,cx
713 push cx
714 call_memcpy32:
715 push dx
716 push ax
717 ifdef LARGE_IMAGES
718 jmp @@memcpy
719 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
720 p386
721 push ecx
722 push eax
723 push 0
724 push edx
725 ifdef NO386
726 p8086
727 endif
728 endif
729 endif
730 @@memcpy:
731 extrn _memcpy32:near
732 call near _memcpy32
733 add sp,14
734 @@skip:
735 ret
737 endp _memcpy_image
739 ;***************************************************************
740 ;void storepage(u32 *dst, u16 src);
741 ;***************************************************************
742 global _storepage:near
743 proc _storepage near
745 pop ax ;caller return address
746 pop bx
747 pop cx
748 push cx
749 push bx
750 push ax
751 ifndef NO386
752 mov edx,[bx]
753 else
754 mov ax,[bx]
755 mov dx,[bx+2]
756 endif
757 storepage: ; storepage(edx,cx)
758 ifndef NO386
759 push 0
760 push 4096
761 push 0
762 else
763 xor bx,bx
764 push bx
765 mov bh,4096/256
766 push bx
767 xor bx,bx
768 push bx
769 endif
770 push cx
771 push ds
772 jmp call_memcpy32
774 endp _storepage
777 ifdef LARGE_IMAGES
778 p386
779 ;***************************************************************
780 ;void reset_bufv(u32 *p);
781 ;***************************************************************
782 global _reset_bufv:near
783 proc _reset_bufv near
785 pop ax ;caller return address
786 pop bx
787 push bx
788 push ax
789 mov [curdata],bx
790 and [dword (data_himem bx).cacheidx],0
791 ret
793 endp _reset_bufv
795 ;***************************************************************
796 ;u32* prev_bufv();
797 ;u32* prev_bufv();
798 ;***************************************************************
799 global _prev_bufv:near
800 global _next_bufv:near
801 proc _prev_bufv near
803 stc
804 db 73h ; jnc
805 _next_bufv:
806 clc
807 sbb ax,ax
808 stc
809 rcl ax,1 ; -1/+1
810 xor ecx,ecx
811 push si
812 mov si,[curdata]
813 add ax,[(data_himem si).cacheidx]
814 test ax,0fc00h
815 jz @@gotpage
816 push ax ; FFFF / 0400
817 sar ax,8 ; FFFC / 0004
818 and al,0fch
819 add [(data_himem si).pageidx],ax
820 mov bx,[(data_himem si).pageidx]
821 lea bx,[(data_himem bx+si).page]
822 mov edx,ds
823 shl edx,4
824 lea cx,[(data_himem si).cache]
825 add edx,ecx
826 mov eax,[bx]
827 or eax,eax
828 jnz @@pageok
829 pop ax
830 xchg ax,bx
831 pop si
832 ret
833 @@pageok:
834 mov cx,4096
835 call memcpy_imagez ; get page
836 pop ax ; FFFF / 0400
837 cbw
838 shr ax,6 ; 03FF / 0000
839 @@gotpage:
840 mov [(data_himem si).cacheidx],ax
841 shl ax,2
842 xchg ax,bx
843 lea ax,[(data_himem bx+si).cache]
844 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
845 jnz @@notfirst2
846 xchg ax,si ; &first
847 @@notfirst2:
848 pop si
849 ret
851 endp _prev_bufv
852 endif
854 ifdef NO386
855 p8086
856 endif
858 ;***************************************************************
859 ;void open_image(const char *name, struct image_himem *m);
860 ;***************************************************************
861 global _open_image:near
862 proc _open_image near
864 pop ax ;caller return address
865 pop bx ; name
866 pop cx ; m
867 push cx
868 push bx
869 push ax
870 push di
871 mov di,cx
872 ifndef NO386
873 xor eax,eax ; 1st loop flag + eos
874 else
875 xor ax,ax ; 1st loop flag + eos
876 endif
877 mov [(image_himem di).next_chunk],offset next_chunk
878 mov [(image_himem di).state],bx
879 push bx
880 @@next:
881 push di
882 call [(image_himem di).next_chunk] ; m->next_chunk()
883 pop di
884 ifndef NO386
885 add eax,3
886 and al,0FCh
887 add [(image_himem di).size],eax ; m->size += m->chunk_size
888 or eax,eax
889 jnz @@next
890 else
891 mov cx,ax
892 or cx,dx
893 add ax,3
894 adc dx,0
895 and al,0FCh
896 add [word (image_himem di).size],ax ; m->size += m->chunk_size
897 adc [word ((image_himem di).size)+2],dx
898 inc cx ; jcxnz
899 loop @@next
900 endif
901 pop [(image_himem di).state]
902 call [(image_himem di).next_chunk] ; m->next_chunk()
903 pop di
904 ret
906 endp _open_image
909 ;***************************************************************
910 ;int read_image(struct image_himem *m, char* data, int sz);
911 ;***************************************************************
912 global _read_image:near
913 proc _read_image near
915 arg m :word, \
916 data :word, \
917 sz :word = PARAM_SIZE
919 push bp
920 mov bp,sp
921 push di
922 ifndef NO386
923 push 0 ; return value
924 else
925 xor ax,ax
926 push ax
927 endif
928 mov di,[m]
929 @@loop:
930 ifndef NO386
931 movzx ecx,[word sz]
932 mov eax,[(image_himem di).chunk_size]
933 cmp ecx,eax
934 jb @@szok
935 else
936 mov cx,[word sz]
937 mov ax,[word (image_himem di).chunk_size]
938 cmp cx,ax
939 jb @@szok
940 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
941 jne @@szok
942 endif
943 xchg ax,cx
944 @@szok:
945 jcxz image_done
946 push cx
947 push [word data]
948 push [word di]
949 call _read
950 pop dx
951 pop bx
952 pop cx
953 jc image_done
954 add bx,ax
955 xor cx,cx
956 ifndef NO386
957 cwde ; ax < 8000h
958 sub [(image_himem di).chunk_size],eax
959 else
960 cwd ; ax < 8000h
961 sub [word (image_himem di).chunk_size],ax
962 sbb [word ((image_himem di).chunk_size)+2],dx
963 jnz @@fill
964 cmp [word (image_himem di).chunk_size],dx
965 endif
966 jnz @@fill
967 dec cx
968 @@fill:
969 test al,3
970 je @@filled
971 mov [bx],dh
972 inc bx
973 inc ax
974 jmp @@fill
975 @@filled:
976 ifndef NO386
977 sub [(image_himem di).remaining],eax
978 else
979 sub [word (image_himem di).remaining],ax
980 sbb [word ((image_himem di).remaining)+2],dx
981 endif
982 add [bp-2-2],ax
983 add [word data],ax
984 sub [word sz],ax
985 pushf
986 jcxz @@same_chunk
987 push di
988 call [(image_himem di).next_chunk]
989 pop di
990 @@same_chunk:
991 popf
992 jnz @@loop
993 image_done:
994 pop ax
995 pop di bp
996 ret
998 endp _read_image
1001 ;***************************************************************
1002 ;unsigned long strtol(const char *s);
1003 ;***************************************************************
1004 global _strtol:near
1005 proc _strtol near
1007 ifndef NO386
1008 pop ax ;caller return address
1009 pop cx ; s
1010 push cx
1011 push ax
1012 xor ebx,ebx
1013 push si
1014 jcxz @@end
1015 mov si,cx
1016 xor ecx,ecx
1017 xor eax,eax
1018 lodsb
1019 mov dx,ax
1020 or al,20h
1021 cmp al,'n' ; vga=normal
1022 je @@vga
1023 dec cx
1024 cmp al,'e' ; vga=extended
1025 je @@vga
1026 dec cx
1027 cmp al,'a' ; vga=ask
1028 jne @@notvga
1029 @@vga:
1030 dec cx
1031 xchg ax,cx
1032 cwd
1033 jmp @@popsiret
1034 @@notvga:
1035 mov cx,10 ; radix
1036 xchg ax,dx
1037 cmp al,'+'
1038 je @@radixskip
1039 cmp al,'-'
1040 clc
1041 jne @@radixkeep
1042 stc
1043 @@radixskip:
1044 lodsb
1045 @@radixkeep:
1046 pushf
1047 cmp al,'0'
1048 jne @@radixok
1049 mov cl,8
1050 lodsb
1051 or al,20h
1052 cmp al,'x'
1053 jne @@radixok
1054 mov cl,16
1055 @@strtollp:
1056 lodsb
1057 @@radixok:
1058 or al,20h
1059 sub al,'0'
1060 jb @@endstrtol
1061 cmp al,9
1062 jbe @@digitok
1063 cmp al,'a'-'0'
1064 jb @@endstrtol
1065 sub al,'a'-'0'-10
1066 @@digitok:
1067 cmp al,cl
1068 jae @@endstrtol
1069 xchg eax,ebx
1070 mul ecx
1071 add eax,ebx
1072 xchg eax,ebx
1073 jmp @@strtollp
1074 @@endstrtol:
1075 mov cl,10
1076 cmp al,'k'-'a'+10
1077 je @@shift
1078 mov cl,20
1079 cmp al,'m'-'a'+10
1080 je @@shift
1081 mov cl,30
1082 cmp al,'g'-'a'+10
1083 jne @@noshift
1084 @@shift:
1085 shl ebx,cl
1086 @@noshift:
1087 popf
1088 jnc @@end
1089 neg ebx
1090 @@end:
1091 push ebx
1092 pop ax
1093 pop dx
1094 @@popsiret:
1095 pop si
1096 else
1097 pop ax ;caller return address
1098 pop cx ; s
1099 push cx
1100 push ax
1101 push si
1102 push di
1103 xor ax,ax
1104 cwd
1105 jcxz @@goend
1106 xchg ax,di
1107 mov si,cx
1108 lodsb
1109 mov bx,ax
1110 or al,20h
1111 mov cx,-1
1112 cmp al,'n' ; vga=normal
1113 je @@vga
1114 dec cx
1115 cmp al,'e' ; vga=extended
1116 je @@vga
1117 dec cx
1118 cmp al,'a' ; vga=ask
1119 jne @@notvga
1120 @@vga:
1121 xchg ax,cx
1122 @@goend:
1123 jmp @@popdisiret
1124 @@notvga:
1125 mov cx,10 ; radix
1126 xchg ax,bx
1127 cmp al,'+'
1128 je @@radixskip
1129 cmp al,'-'
1130 clc
1131 jne @@radixkeep
1132 stc
1133 @@radixskip:
1134 lodsb
1135 @@radixkeep:
1136 pushf
1137 cmp al,'0'
1138 jne @@radixok
1139 mov cl,8
1140 lodsb
1141 or al,20h
1142 cmp al,'x'
1143 jne @@radixok
1144 mov cl,16
1145 @@strtollp:
1146 lodsb
1147 @@radixok:
1148 or al,20h
1149 sub al,'0'
1150 jb @@endstrtol
1151 cmp al,9
1152 jbe @@digitok
1153 cmp al,'a'-'0'
1154 jb @@endstrtol
1155 sub al,'a'-'0'-10
1156 @@digitok:
1157 cmp al,cl
1158 jae @@endstrtol
1160 push ax
1161 push si
1162 push dx
1163 xchg ax,di
1164 mul cx
1165 xchg ax,di
1166 xchg ax,dx
1167 xchg ax,si
1168 pop ax
1169 mul cx
1170 add ax,si
1171 pop si
1172 xchg ax,dx
1173 pop ax
1174 mov ah,0
1175 add di,ax
1176 adc dx,0
1178 jmp @@strtollp
1179 @@endstrtol:
1180 mov cl,10
1181 cmp al,'k'-'a'+10
1182 je @@shift
1183 mov cl,20
1184 cmp al,'m'-'a'+10
1185 je @@shift
1186 mov cl,30
1187 cmp al,'g'-'a'+10
1188 jne @@noshift
1189 @@shift:
1190 rcl di,1
1191 shl dx,1
1192 loop @@shift
1193 @@noshift:
1194 popf
1195 jnc @@end
1196 not dx
1197 neg di
1198 jne @@end
1199 inc dx
1200 @@end:
1201 xchg ax,di
1202 @@popdisiret:
1203 pop di
1204 pop si
1205 endif
1206 ret
1208 endp _strtol
1211 ifdef NO386
1212 ;***************************************************************
1213 ;u16 topseg();
1214 ;***************************************************************
1215 global _topseg:near
1216 proc _topseg near
1218 int 12h
1219 jnc @@max640k
1220 mov ax,640 ; 9000
1221 @@max640k:
1222 dec ax
1223 and al,0C0h
1224 mov cl,6
1225 shl ax,cl
1226 ret
1228 endp _topseg
1229 endif
1231 ifdef EXTRA
1232 p8086
1233 ;***************************************************************
1234 ;char *progname(void)
1235 ;***************************************************************
1236 global _progname:near
1237 proc _progname near
1239 push si di es
1240 mov ah,30h
1241 int 21h
1242 xor di,di
1243 cmp al,3
1244 mov ax,di
1245 jb @@skip
1246 ;mov es,[cs:2Ch]
1247 mov es,[di+2Ch]
1248 mov cx,sp ; big enough
1249 @@loop:
1250 repne
1251 scasb
1252 scasb
1253 jne @@loop
1254 inc di
1255 inc di
1256 mov si,di ; progname @es:di
1257 repne
1258 scasb
1259 mov cx,di
1260 sub cx,si ; progname len
1261 call malloc_or_die ; keep cx
1262 mov di,ax
1263 push ds
1264 push es
1265 pop ds
1266 pop es
1267 rep
1268 movsb
1269 push es
1270 pop ds
1271 @@skip:
1272 pop es di si
1273 ret
1275 endp _progname
1278 ;***************************************************************
1279 ;void chdirname(char *path)
1280 ;***************************************************************
1281 global _chdirname:near
1282 proc _chdirname near
1284 pop ax
1285 pop bx
1286 push bx
1287 push ax
1289 cmp [byte bx+1],3Ah ; ':'
1290 jne @@nodisk
1291 mov dl,20h
1292 or dl,[bx]
1293 sub dl,61h
1294 mov ah,0Eh
1295 int 21h
1296 inc bx
1297 inc bx
1298 @@nodisk:
1299 xor cx,cx
1300 @@next:
1301 mov al,[bx]
1302 cmp al,5Ch
1303 jne @@tsteos
1304 mov dx,bx
1305 inc cx
1306 @@tsteos:
1307 inc bx
1308 or al,al
1309 jnz @@next
1310 jcxz @@end
1311 mov bx,dx
1312 push [word bx]
1313 mov [bx],al
1314 stc
1315 mov ax,713Bh ; chdir long filename (ds:dx)
1316 int 21h
1317 mov ah,3Bh ; chdir(ds:dx)
1318 jnc chdirdone
1319 int 21h
1320 chdirdone:
1321 pop [word bx]
1322 @@end:
1323 ret
1325 endp _chdirname
1328 ;***************************************************************
1329 ;char *ultoa(unsigned long n);
1330 ;***************************************************************
1331 global _ultoa:near
1332 proc _ultoa near
1334 pop ax
1335 pop cx
1336 pop dx
1337 push dx
1338 push cx
1339 push ax ; DX:CX = n
1340 push si
1341 mov si,10
1342 mov bx,offset ultoabuf+11
1343 @@loop:
1344 dec bx
1345 xchg ax,dx
1346 xor dx,dx
1347 div si ; DX:AX = 0000:hi(n)
1348 xchg ax,cx ; CX = hi(n)/10
1349 div si ; DX:AX = hi(n)%10:lo(n)
1350 xchg ax,cx ; CX = lo(n/10)
1351 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1352 add al,'0'
1353 mov [bx],al
1354 mov ax,cx
1355 or ax,dx
1356 jnz @@loop
1357 xchg ax,bx
1358 pop si
1359 ret
1361 endp _ultoa
1364 ;***************************************************************
1365 ;unsigned long kver2ul(char *kernel_version);
1366 ;***************************************************************
1367 global _kver2ul:near
1368 proc _kver2ul near
1370 pop bx
1371 pop ax
1372 push ax
1373 push bx
1374 push si
1375 xchg ax,si
1376 xor bx,bx
1377 mov cx,304h
1378 @@number:
1379 xor ax,ax
1380 cwd
1381 @@digit:
1382 shl al,cl
1383 shl ax,cl
1384 lodsb
1385 sub al,30h
1386 cmp al,9
1387 jbe @@digit
1388 mov dl,bh
1389 mov bh,bl
1390 mov bl,ah
1391 dec ch
1392 jnz @@number
1393 xchg ax,bx
1394 pop si
1395 kver2ulret:
1396 ret
1398 endp _kver2ul
1401 ;***************************************************************
1402 ;void try_default_args();
1403 ;***************************************************************
1404 global _try_default_args:near
1405 proc _try_default_args near
1407 mov bx,offset tazboot_cmd
1408 call open
1409 jc kver2ulret
1410 mov cx,4096
1411 mov di,[_heap_top]
1412 push cx
1413 extrn read_cmdline:near
1414 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1416 endp _try_default_args
1418 endif
1420 ends _TEXT
1422 end
1424 ;###### END OF FILE ############################################