wok-current view linld/stuff/src/CRTL.ASM @ rev 20510

Up acl-dev (2.2.53)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Oct 31 15:13:42 2018 +0100 (2018-10-31)
parents 049ced0bd387
children d7919052f62f
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 or 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 @@putsz:
192 mov dl,[bx]
193 inc bx
194 or dl,dl
195 jne @@putcz ; ZF=1 (for malloc failure)
196 ret
198 endp _puts
201 ;***************************************************************
202 ;int fileattr(const char* name);
203 ;***************************************************************
204 global _fileattr:near
205 proc _fileattr near
207 pop ax ;caller return address
208 pop dx ; name
209 push dx
210 push ax
211 mov ax,4300h
212 int 21h
213 xchg ax,cx
214 jmp chkc
216 endp _fileattr
219 ;***************************************************************
220 ;int open(const char* name, int flags=O_RDONLY);
221 ;***************************************************************
222 global _open:near
223 proc _open near
225 pop ax ;caller return address
226 pop bx ; name
227 push bx
228 push ax
229 global open:near ; open(bx)
230 open:
231 mov dx,bx
232 ;mov cl,0 ; attribute mask
233 mov ax,3d00h ; read-only+compatibility
234 dos:
235 int 21h
236 chkc:
237 jnc doret
238 fail:
239 sbb ax,ax ; ax=-1 CF
240 cwd
241 doret:
242 ifndef NO386
243 push dx ; see next_chunk:lseek
244 push ax
245 pop eax
246 endif
247 ret
249 endp _open
252 ;***************************************************************
253 ;int close(int fd);
254 ;***************************************************************
255 global _close:near
256 proc _close near
258 pop ax ;caller return address
259 pop bx ; fd
260 push bx
261 push ax
262 global close:near ; close(bx)
263 close:
264 mov ah,3Eh
265 or bx,bx
266 jnz dos
267 ret
269 endp _close
272 ;***************************************************************
273 ;int read(int fd, void* data, int sz);
274 ;int write(int fd, const void* data, int sz);
275 ;***************************************************************
276 global _read:near
277 proc _read near
279 ifdef WRITE
280 stc
281 db 0B0h ; mov al,im
282 global _write:near
283 clc
284 endif
285 pop ax ;caller return address
286 pop bx ; fd
287 pop dx ; data
288 pop cx ; sz
289 push cx
290 push dx
291 push bx
292 push ax
293 ifdef WRITE
294 mov ah,40h
295 sbb ah,0
296 else
297 mov ah,3Fh
298 endif
299 jcxz fail
300 jmp dos
302 endp _read
304 proc _lseekset near
305 ;ifdef EXTRA
306 ;***************************************************************
307 ;long lseekset(int fd, unsigned long sz);
308 ;***************************************************************
310 global _lseekset:near
312 pop ax ;caller return address
313 pop bx ; fd
314 pop dx ; sz lo
315 pop cx ; sz hi
316 push cx
317 push dx
318 push bx
319 push ax
320 ;endif
321 ; global lseekset:near
322 lseekset:
323 clc
324 db 0B0h ; mov al,im
325 ; global rewind:near
326 rewind: ; rewind(bx)
327 stc
328 mov ax,4200h
329 jnc dos
330 lseek0: ; lseek0(bx,ax=dir)
331 cwd
332 xor cx,cx
333 jmp dos
335 endp _lseekset
337 ifdef EXTRA
338 struc isostate ; struct isostate {
339 fd dw ? ; 0 int fd;
340 fileofs dd ? ; 2 unsigned long fileofs;
341 filesize dd ? ; 6 unsigned long filesize;
342 filemod dw ? ;10 unsigned short filemod;
343 filename dw ? ;12 char *filename;
344 dirofs dd ? ;14 unsigned long dirofs;
345 dirsize dd ? ;16 unsigned long dirsize;
346 curdirofs dd ? ;20 unsigned long curdirofs;
347 curdirsize dd ? ;24 unsigned long curdirsize;
348 curpos dd ? ;28 unsigned long curpos;
349 ends ; } isostate;
350 ;***************************************************************
351 ;unsigned long isolseek(const unsigned long *offset);
352 ;***************************************************************
353 global _isolseek:near
354 proc _isolseek near
356 pop ax
357 pop bx
358 push bx
359 push ax
360 mov dx,[bx]
361 mov cx,[bx+2]
362 extrn _isostate:isostate
363 mov bx,[_isostate.fd]
364 jmp lseekset ; (bx=fd, sz=cx:dx)
366 endp _isolseek
367 endif
370 ;***************************************************************
371 ;int strhead(const char* a,const char* b);
372 ;***************************************************************
373 global _strhead:near
374 proc _strhead near
376 pop cx ;caller return address
377 pop bx ; a
378 pop ax ; b
379 push ax
380 push bx
381 push cx
382 @@loop:
383 xchg ax,bx
384 mov cl,[bx] ; cl = *b++
385 inc bx
386 or cl,cl ; clear C
387 jz fail ; return 0
388 xchg ax,bx
389 xor cl,[bx] ; cl -= *a++
390 inc bx
391 and cl,0dfh ; case insensitive
392 jz @@loop
393 ret ; return b (is not 0)
395 endp _strhead
398 ;***************************************************************
399 ;char* malloc_or_die(unsigned size);
400 ;***************************************************************
401 global _malloc_or_die:near
402 proc _malloc_or_die near
404 pop ax ;caller return address
405 pop cx ; size
406 push cx
407 push ax
408 global malloc_or_die:near ; malloc_or_die(cx)
409 malloc_or_die:
410 mov ax,[_heap_top] ; return value
411 mov bx,sp
412 add bh,-14h ; MIN_STACK=_1k+PAGE_SIZE
413 sub bx,ax ; can't overflow
414 cmp bx,cx
415 mov bx,offset msg_malloc
416 jb die
417 add [_heap_top],cx ; _BEG has zero'd heap
418 ret
420 endp _malloc_or_die
423 ;***************************************************************
424 ;int die(const char* msg);
425 ;int exit();
426 ;int abort();
427 ;***************************************************************
428 global _die:near
429 proc _die near
431 pop ax ;caller return address
432 pop bx ; s
433 push bx
434 push ax
435 global die:near ; die(bx)
436 die:
437 call puts
438 ; global _exit:near
439 _exit:
440 mov al,[_no_exit]
441 cmp al,0
442 jne @@hang
443 extrn exit:near
444 inc ax
445 jmp near exit
446 @@hang:
447 mov bx, offset msg_hang
448 call puts
449 ; global _abort:near
450 _abort:
451 cli
452 @@stop:
453 hlt
454 jmp @@stop
456 endp _die
458 struc image_himem ;struct image_himem {
459 fd dw ? ; 0 int fd;
460 fallback dd ? ; 2 u32 fallback;
461 size dd ? ; 6 u32 size;
462 remaining dd ? ;10 u32 remaining;
463 buf dd ? ;14 u32 buf;
464 bufv dw ? ;18 u32 *bufv;
465 errmsg dw ? ;20 char *errmsg;
466 chunk_size dd ? ;22 u32 chunk_size;
467 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
468 state dw ? ;28 u16 state;
469 fd2close dw ? ;30 u16 fd2close;
470 ends ;};
472 ;***************************************************************
473 ;long next_chunk(struct image_himem *di);
474 ;***************************************************************
475 proc next_chunk near
477 push si
478 mov bx,[(image_himem di).fd]
479 call close
480 ifndef NO386
481 xor eax,eax
482 else
483 xor ax,ax
484 cwd
485 endif
486 mov [(image_himem di).fd],ax
487 mov bx,[(image_himem di).state]
488 cmp al,[bx] ; ""
489 jz @@end
490 mov si,bx
491 @@scan:
492 lodsb
493 mov cx,si
494 cmp al,','
495 jz @@eos
496 cmp al,0
497 jnz @@scan
498 dec cx
499 @@eos:
500 mov [(image_himem di).state],cx
501 dec si
502 push [word si]
503 mov [byte si],ah ; set temp eos
504 call open
505 pop [word si] ; restore string
506 jc @@die
507 mov [(image_himem di).fd],ax
508 mov [(image_himem di).fd2close],ax
509 xchg ax,bx
510 mov ax,4202h ; SEEK_END
511 call lseek0
512 @@die:
513 mov bx,[(image_himem di).errmsg]
514 jc die
515 mov bx,[(image_himem di).fd]
516 ifndef NO386
517 push eax
518 call rewind
519 pop eax
520 @@end:
521 mov [(image_himem di).chunk_size],eax
522 else
523 push ax
524 push dx
525 call rewind
526 pop dx
527 pop ax
528 @@end:
529 mov [word (image_himem di).chunk_size],ax
530 mov [word ((image_himem di).chunk_size)+2],dx
531 endif
532 pop si
533 ret
535 endp next_chunk
538 ifdef LARGE_IMAGES
539 struc data_himem ;struct data_himem {
540 first dd ? ; 0 u32 first;
541 cacheidx dw ? ; 4 int cacheidx;
542 pageidx dw ? ; 6 int pageidx;
543 cache dd 1024 dup(?) ; 8 int cache;
544 page dd 1024 dup(?) ;4104 int page;
545 ends ;}; // size=8200
546 endif
548 ;***************************************************************
549 ;u32* malloc_bufv_or_die(struct image_himem *m);
550 ;***************************************************************
551 global _malloc_bufv_or_die:near
552 proc _malloc_bufv_or_die near
554 p386
555 pop bx ;caller return address
556 pop ax
557 push ax
558 push bx
559 push si
560 xchg ax,si
561 ifdef LARGE_IMAGES
562 mov cx,[word ((image_himem si).size) + 2]
563 shr cx,4 ; pages index size = size >> 20
564 add cx,8+4096+8
565 call malloc_or_die
566 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
567 add ecx,[(image_himem si).size]
568 shr ecx,12
569 mov [curdata],ax
570 else
571 mov ecx,[(image_himem si).size]
572 dec ecx
573 shr ecx,12
574 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
575 push cx
576 inc cx ; cnt+1
577 shl cx,2 ; bufv => vcpi => vm86
578 ; our malloc zeroes allocated mem: bufv[cnt]=0;
579 ; Allocate pages, storing addrs in addrbuf
580 call malloc_or_die
581 pop cx
582 push ax
583 endif
584 mov [(image_himem si).bufv],ax
585 xchg ax,si
586 @@vcpi_alloc:
587 xor edx,edx
588 mov ax,0DE04h
589 int 67h
590 or ah,ah
591 mov bx,offset vcpi_alloc_err
592 jnz die
593 ; for (i = cnt-1; i >= 0; i--)
594 ifdef LARGE_IMAGES
595 mov eax,ecx
596 dec eax
597 else
598 mov ax,cx
599 dec ax
600 cwde
601 endif
602 shl eax,12 ; i*_4k
603 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
604 extrn _imgs
605 mov bx,offset _imgs+2
606 push eax
607 add eax,[bx-2+2]
608 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
609 pop eax ; i*_4k
610 jbe @@pmok
611 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
612 jae @@vcpi_alloc
613 @@pmok:
614 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
615 extrn _imgs
616 mov bx,offset _imgs+32+2
617 add eax,[bx-2+2] ; +initrd.fallback
618 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
619 ja @@initrdok
620 mov eax,[bx-2+6] ; initrd.size
621 add eax,[bx-2+2] ; +initrd.fallback
622 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
623 @@jnc_vcpi_alloc:
624 ja @@vcpi_alloc
625 @@initrdok:
626 ifdef LARGE_IMAGES
627 cmp [(data_himem si).first],0
628 jne @@notfirst
629 mov [(data_himem si).first],edx
630 @@notfirst:
631 mov bx,[(data_himem si).cacheidx]
632 cmp bh,4
633 jae @@nextpage
634 shl bx,2
635 inc [(data_himem si).cacheidx]
636 mov [(data_himem bx+si).cache],edx
637 loopd @@vcpi_alloc
638 mov [(data_himem bx+si).cache],ecx ; last is 0
639 @@nextpage:
640 and [(data_himem si).cacheidx],0
641 mov bx,[(data_himem si).pageidx]
642 mov [(data_himem bx+si).page],edx
643 add [(data_himem si).pageidx],4
644 push cx
645 lea cx,[(data_himem si).cache]
646 ifdef NO386
647 push edx
648 pop dx
649 pop ax
650 endif
651 call storepage ; storepage(edx,cx)
652 pop cx
653 or ecx,ecx ; clear C
654 jnz @@jnc_vcpi_alloc
655 mov [dword (data_himem si).cacheidx],ecx
656 xchg ax,si
657 else
658 mov [si],edx
659 lodsd ; si=+4
660 loop @@vcpi_alloc
661 pop ax
662 endif
663 pop si
664 ret
665 ifdef NO386
666 p8086
667 endif
669 endp _malloc_bufv_or_die
672 ;***************************************************************
673 ; void memcpy_image(struct image_himem *m);
674 ;***************************************************************
675 global _memcpy_image:near
676 proc _memcpy_image near
678 pop ax ;caller return address
679 pop bx
680 push bx
681 push ax
682 ifndef NO386
683 mov edx,[(image_himem bx).fallback]
684 mov eax,[(image_himem bx).buf]
685 cmp eax,edx ; if (m->fallback != m->buf)
686 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
687 ifdef LARGE_IMAGES
688 mov ecx,[(image_himem bx).size]
689 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
690 push ecx
691 else
692 push [(image_himem bx).size]
693 endif
694 push eax
695 push 0
696 call_memcpy32:
697 push edx
698 else
699 mov ax,[word ((image_himem bx).fallback)]
700 mov dx,[word ((image_himem bx).fallback)+2]
701 mov cx,[word ((image_himem bx).buf)]
702 cmp ax,cx ; if (m->fallback != m->buf)
703 jnz @@do
704 cmp dx,[word ((image_himem bx).buf)+2]
705 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
706 @@do:
707 push [word ((image_himem bx).size)+2]
708 push [word ((image_himem bx).size)]
709 push [word ((image_himem bx).buf)+2]
710 push cx
711 xor cx,cx
712 push cx
713 call_memcpy32:
714 push dx
715 push ax
716 ifdef LARGE_IMAGES
717 jmp @@memcpy
718 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
719 p386
720 push ecx
721 push eax
722 push 0
723 push edx
724 ifdef NO386
725 p8086
726 endif
727 endif
728 endif
729 @@memcpy:
730 extrn _memcpy32:near
731 call near _memcpy32
732 add sp,14
733 @@skip:
734 ret
736 endp _memcpy_image
738 ;***************************************************************
739 ;void storepage(u32 *dst, u16 src);
740 ;***************************************************************
741 global _storepage:near
742 proc _storepage near
744 pop ax ;caller return address
745 pop bx
746 pop cx
747 push cx
748 push bx
749 push ax
750 ifndef NO386
751 mov edx,[bx]
752 else
753 mov ax,[bx]
754 mov dx,[bx+2]
755 endif
756 storepage: ; storepage(edx,cx)
757 ifndef NO386
758 push 0
759 push 4096
760 push 0
761 else
762 xor bx,bx
763 push bx
764 mov bh,4096/256
765 push bx
766 xor bx,bx
767 push bx
768 endif
769 push cx
770 push ds
771 jmp call_memcpy32
773 endp _storepage
776 ifdef LARGE_IMAGES
777 p386
778 ;***************************************************************
779 ;void reset_bufv(u32 *p);
780 ;***************************************************************
781 global _reset_bufv:near
782 proc _reset_bufv near
784 pop bx ;caller return address
785 pop ax
786 push ax
787 push bx
788 mov [curdata],ax
789 and [dword (data_himem bx).cacheidx],0
790 ret
792 endp _reset_bufv
794 ;***************************************************************
795 ;u32* prev_bufv();
796 ;u32* prev_bufv();
797 ;***************************************************************
798 global _prev_bufv:near
799 global _next_bufv:near
800 proc _prev_bufv near
802 stc
803 db 73h ; jnc
804 _next_bufv:
805 clc
806 sbb ax,ax
807 stc
808 rcl ax,1 ; -1/+1
809 xor ecx,ecx
810 push si
811 mov si,[curdata]
812 add ax,[(data_himem si).cacheidx]
813 test ax,0fc00h
814 jz @@gotpage
815 push ax ; FFFF / 0400
816 sar ax,8 ; FFFC / 0004
817 and al,0fch
818 add [(data_himem si).pageidx],ax
819 mov bx,[(data_himem si).pageidx]
820 lea bx,[(data_himem bx+si).page]
821 mov edx,ds
822 shl edx,4
823 lea cx,[(data_himem si).cache]
824 add edx,ecx
825 mov eax,[bx]
826 or eax,eax
827 jnz @@pageok
828 pop ax
829 xchg ax,bx
830 pop si
831 ret
832 @@pageok:
833 mov cx,4096
834 call memcpy_imagez ; get page
835 pop ax ; FFFF / 0400
836 cbw
837 shr ax,6 ; 03FF / 0000
838 @@gotpage:
839 mov [(data_himem si).cacheidx],ax
840 shl ax,2
841 xchg ax,bx
842 lea ax,[(data_himem bx+si).cache]
843 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
844 jnz @@notfirst2
845 xchg ax,si ; &first
846 @@notfirst2:
847 pop si
848 ret
850 endp _prev_bufv
851 endif
853 ifdef NO386
854 p8086
855 endif
857 ;***************************************************************
858 ;void open_image(const char *name, struct image_himem *m);
859 ;***************************************************************
860 global _open_image:near
861 proc _open_image near
863 pop cx ;caller return address
864 pop bx ; name
865 pop ax ; m
866 push ax
867 push bx
868 push cx
869 push di
870 xchg ax,di
871 mov [(image_himem di).next_chunk],offset next_chunk
872 mov [(image_himem di).state],bx
873 push bx
874 @@next:
875 call [(image_himem di).next_chunk] ; m->next_chunk()
876 ifndef NO386
877 add eax,3
878 and al,0FCh
879 add [(image_himem di).size],eax ; m->size += m->chunk_size
880 or eax,eax
881 jnz @@next
882 else
883 mov cx,ax
884 or cx,dx
885 add ax,3
886 adc dx,0
887 and al,0FCh
888 add [word (image_himem di).size],ax ; m->size += m->chunk_size
889 adc [word ((image_himem di).size)+2],dx
890 inc cx ; jcxnz
891 loop @@next
892 endif
893 pop [(image_himem di).state]
894 call [(image_himem di).next_chunk] ; m->next_chunk()
895 pop di
896 ret
898 endp _open_image
901 ;***************************************************************
902 ;int read_image(struct image_himem *m, char* data, int sz);
903 ;***************************************************************
904 global _read_image:near
905 proc _read_image near
907 arg m :word, \
908 data :word, \
909 sz :word = PARAM_SIZE
911 push bp
912 mov bp,sp
913 push di
914 ifndef NO386
915 push 0 ; return value
916 else
917 xor ax,ax
918 push ax
919 endif
920 mov di,[m]
921 @@loop:
922 ifndef NO386
923 movzx ecx,[word sz]
924 mov eax,[(image_himem di).chunk_size]
925 cmp ecx,eax
926 jb @@szok
927 else
928 mov cx,[word sz]
929 mov ax,[word (image_himem di).chunk_size]
930 cmp cx,ax
931 jb @@szok
932 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
933 jne @@szok
934 endif
935 xchg ax,cx
936 @@szok:
937 jcxz image_done
938 push cx
939 push [word data]
940 push [word di]
941 call _read
942 pop dx
943 pop bx
944 pop cx
945 jc image_done
946 add bx,ax
947 xor cx,cx
948 ifndef NO386
949 cwde ; ax < 8000h
950 sub [(image_himem di).chunk_size],eax
951 else
952 cwd ; ax < 8000h
953 sub [word (image_himem di).chunk_size],ax
954 sbb [word ((image_himem di).chunk_size)+2],dx
955 jnz @@fill
956 cmp [word (image_himem di).chunk_size],dx
957 endif
958 jnz @@fill
959 dec cx
960 @@fill:
961 test al,3
962 je @@filled
963 mov [bx],dh
964 inc bx
965 inc ax
966 jmp @@fill
967 @@filled:
968 ifndef NO386
969 sub [(image_himem di).remaining],eax
970 else
971 sub [word (image_himem di).remaining],ax
972 sbb [word ((image_himem di).remaining)+2],dx
973 endif
974 add [bp-2-2],ax
975 add [word data],ax
976 sub [word sz],ax
977 pushf
978 jcxz @@same_chunk
979 call [(image_himem di).next_chunk]
980 @@same_chunk:
981 popf
982 jnz @@loop
983 image_done:
984 pop ax
985 pop di bp
986 ret
988 endp _read_image
991 ;***************************************************************
992 ;unsigned long strtol(const char *s);
993 ;***************************************************************
994 global _strtol:near
995 proc _strtol near
997 ifndef NO386
998 pop ax ;caller return address
999 pop cx ; s
1000 push cx
1001 push ax
1002 xor ebx,ebx
1003 push si
1004 jcxz @@end
1005 mov si,cx
1006 xor ecx,ecx
1007 xor eax,eax
1008 lodsb
1009 mov dx,ax
1010 or al,20h
1011 cmp al,'n' ; vga=normal
1012 je @@vga
1013 dec cx
1014 cmp al,'e' ; vga=extended
1015 je @@vga
1016 dec cx
1017 cmp al,'a' ; vga=ask
1018 jne @@notvga
1019 @@vga:
1020 dec cx
1021 xchg ax,cx
1022 cwd
1023 jmp @@popsiret
1024 @@notvga:
1025 mov cx,10 ; radix
1026 xchg ax,dx
1027 cmp al,'+'
1028 je @@radixskip
1029 cmp al,'-'
1030 clc
1031 jne @@radixkeep
1032 stc
1033 @@radixskip:
1034 lodsb
1035 @@radixkeep:
1036 pushf
1037 cmp al,'0'
1038 jne @@radixok
1039 mov cl,8
1040 lodsb
1041 or al,20h
1042 cmp al,'x'
1043 jne @@radixok
1044 mov cl,16
1045 @@strtollp:
1046 lodsb
1047 @@radixok:
1048 or al,20h
1049 sub al,'0'
1050 jb @@endstrtol
1051 cmp al,9
1052 jbe @@digitok
1053 cmp al,'a'-'0'
1054 jb @@endstrtol
1055 sub al,'a'-'0'-10
1056 @@digitok:
1057 cmp al,cl
1058 jae @@endstrtol
1059 xchg eax,ebx
1060 mul ecx
1061 add eax,ebx
1062 xchg eax,ebx
1063 jmp @@strtollp
1064 @@endstrtol:
1065 mov cl,10
1066 cmp al,'k'-'a'+10
1067 je @@shift
1068 mov cl,20
1069 cmp al,'m'-'a'+10
1070 je @@shift
1071 mov cl,30
1072 cmp al,'g'-'a'+10
1073 jne @@noshift
1074 @@shift:
1075 shl ebx,cl
1076 @@noshift:
1077 popf
1078 jnc @@end
1079 neg ebx
1080 @@end:
1081 push ebx
1082 pop ax
1083 pop dx
1084 @@popsiret:
1085 pop si
1086 else
1087 pop ax ;caller return address
1088 pop cx ; s
1089 push cx
1090 push ax
1091 push si
1092 push di
1093 xor ax,ax
1094 cwd
1095 jcxz @@goend
1096 xchg ax,di
1097 mov si,cx
1098 lodsb
1099 mov bx,ax
1100 or al,20h
1101 mov cx,-1
1102 cmp al,'n' ; vga=normal
1103 je @@vga
1104 dec cx
1105 cmp al,'e' ; vga=extended
1106 je @@vga
1107 dec cx
1108 cmp al,'a' ; vga=ask
1109 jne @@notvga
1110 @@vga:
1111 xchg ax,cx
1112 @@goend:
1113 jmp @@popdisiret
1114 @@notvga:
1115 mov cx,10 ; radix
1116 xchg ax,bx
1117 cmp al,'+'
1118 je @@radixskip
1119 cmp al,'-'
1120 clc
1121 jne @@radixkeep
1122 stc
1123 @@radixskip:
1124 lodsb
1125 @@radixkeep:
1126 pushf
1127 cmp al,'0'
1128 jne @@radixok
1129 mov cl,8
1130 lodsb
1131 or al,20h
1132 cmp al,'x'
1133 jne @@radixok
1134 mov cl,16
1135 @@strtollp:
1136 lodsb
1137 @@radixok:
1138 or al,20h
1139 sub al,'0'
1140 jb @@endstrtol
1141 cmp al,9
1142 jbe @@digitok
1143 cmp al,'a'-'0'
1144 jb @@endstrtol
1145 sub al,'a'-'0'-10
1146 @@digitok:
1147 cmp al,cl
1148 jae @@endstrtol
1150 push ax
1151 push si
1152 push dx
1153 xchg ax,di
1154 mul cx
1155 xchg ax,di
1156 xchg ax,dx
1157 xchg ax,si
1158 pop ax
1159 mul cx
1160 add ax,si
1161 pop si
1162 xchg ax,dx
1163 pop ax
1164 mov ah,0
1165 add di,ax
1166 adc dx,0
1168 jmp @@strtollp
1169 @@endstrtol:
1170 mov cl,10
1171 cmp al,'k'-'a'+10
1172 je @@shift
1173 mov cl,20
1174 cmp al,'m'-'a'+10
1175 je @@shift
1176 mov cl,30
1177 cmp al,'g'-'a'+10
1178 jne @@noshift
1179 @@shift:
1180 rcl di,1
1181 shl dx,1
1182 loop @@shift
1183 @@noshift:
1184 popf
1185 jnc @@end
1186 not dx
1187 neg di
1188 jne @@end
1189 inc dx
1190 @@end:
1191 xchg ax,di
1192 @@popdisiret:
1193 pop di
1194 pop si
1195 endif
1196 ret
1198 endp _strtol
1201 ifdef NO386
1202 ;***************************************************************
1203 ;u16 topseg();
1204 ;***************************************************************
1205 global _topseg:near
1206 proc _topseg near
1208 int 12h
1209 jnc @@max640k
1210 mov ax,640 ; 9000
1211 @@max640k:
1212 dec ax
1213 and al,0C0h
1214 mov cl,6
1215 shl ax,cl
1216 ret
1218 endp _topseg
1219 endif
1221 ifdef EXTRA
1222 p8086
1223 ;***************************************************************
1224 ;char *progname(void)
1225 ;***************************************************************
1226 global _progname:near
1227 proc _progname near
1229 push si di es
1230 mov ah,30h
1231 int 21h
1232 xor di,di
1233 cmp al,3
1234 mov ax,di
1235 jb @@skip
1236 ;mov es,[cs:2Ch]
1237 mov es,[di+2Ch]
1238 mov cx,sp ; big enough
1239 @@loop:
1240 repne
1241 scasb
1242 scasb
1243 jne @@loop
1244 inc di
1245 inc di
1246 mov si,di ; progname @es:di
1247 repne
1248 scasb
1249 mov cx,di
1250 sub cx,si ; progname len
1251 call malloc_or_die ; keep cx
1252 mov di,ax
1253 push ds
1254 push es
1255 pop ds
1256 pop es
1257 rep
1258 movsb
1259 push es
1260 pop ds
1261 @@skip:
1262 pop es di si
1263 ret
1265 endp _progname
1268 ;***************************************************************
1269 ;void chdirname(char *path)
1270 ;***************************************************************
1271 global _chdirname:near
1272 proc _chdirname near
1274 pop ax
1275 pop bx
1276 push bx
1277 push ax
1279 cmp [byte bx+1],3Ah ; ':'
1280 jne @@nodisk
1281 mov dl,20h
1282 or dl,[bx]
1283 sub dl,61h
1284 mov ah,0Eh
1285 int 21h
1286 inc bx
1287 inc bx
1288 @@nodisk:
1289 xor cx,cx
1290 @@next:
1291 mov al,[bx]
1292 cmp al,5Ch
1293 jne @@tsteos
1294 mov dx,bx
1295 inc cx
1296 @@tsteos:
1297 inc bx
1298 or al,al
1299 jnz @@next
1300 jcxz @@end
1301 mov bx,dx
1302 push [word bx]
1303 mov [bx],al
1304 stc
1305 mov ax,713Bh ; chdir long filename (ds:dx)
1306 int 21h
1307 mov ah,3Bh ; chdir(ds:dx)
1308 jnc @@chdirdone
1309 int 21h
1310 @@chdirdone:
1311 pop [word bx]
1312 @@end:
1313 ret
1315 endp _chdirname
1318 ;***************************************************************
1319 ;char *ultoa(unsigned long n);
1320 ;***************************************************************
1321 global _ultoa:near
1322 proc _ultoa near
1324 pop ax
1325 pop cx
1326 pop dx
1327 push dx
1328 push cx
1329 push ax ; DX:CX = n
1330 push si
1331 mov si,10
1332 mov bx,offset ultoabuf+11
1333 @@loop:
1334 dec bx
1335 xchg ax,dx
1336 xor dx,dx
1337 div si ; DX:AX = 0000:hi(n)
1338 xchg ax,cx ; CX = hi(n)/10
1339 div si ; DX:AX = hi(n)%10:lo(n)
1340 xchg ax,cx ; CX = lo(n/10)
1341 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1342 add al,'0'
1343 mov [bx],al
1344 mov ax,cx
1345 or ax,dx
1346 jnz @@loop
1347 xchg ax,bx
1348 pop si
1349 ret
1351 endp _ultoa
1354 ;***************************************************************
1355 ;unsigned long kver2ul(char *kernel_version);
1356 ;***************************************************************
1357 global _kver2ul:near
1358 proc _kver2ul near
1360 pop bx
1361 pop ax
1362 push ax
1363 push bx
1364 push si
1365 xchg ax,si
1366 xor bx,bx
1367 mov cx,304h
1368 @@number:
1369 xor ax,ax
1370 cwd
1371 @@digit:
1372 shl al,cl
1373 shl ax,cl
1374 lodsb
1375 sub al,30h
1376 cmp al,9
1377 jbe @@digit
1378 mov dl,bh
1379 mov bh,bl
1380 mov bl,ah
1381 dec ch
1382 jnz @@number
1383 xchg ax,bx
1384 pop si
1385 kver2ulret:
1386 ret
1388 endp _kver2ul
1391 ;***************************************************************
1392 ;void try_default_args();
1393 ;***************************************************************
1394 global _try_default_args:near
1395 proc _try_default_args near
1397 mov bx,offset tazboot_cmd
1398 call open
1399 jc kver2ulret
1400 mov cx,4096
1401 mov di,[_heap_top]
1402 push cx
1403 extrn read_cmdline:near
1404 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1406 endp _try_default_args
1408 endif
1410 ends _TEXT
1412 end
1414 ;###### END OF FILE ############################################