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

linld: tiny shrink
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Nov 11 10:57:19 2017 +0100 (2017-11-11)
parents 9e8f9b54bd83
children d78aa8a969f4
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:word
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 failure",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 ;***************************************************************
109 ;void* malloc(unsigned sz);
110 ;***************************************************************
111 global _malloc:near
112 proc _malloc near
114 pop ax ;caller return address
115 pop cx ; sz
116 push cx
117 push ax
118 global malloc:near ; malloc(cx)
119 malloc: ; keep CX, use AX,BX
120 mov ax,[_heap_top]
121 mov bx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
122 add bx,sp
123 sub bx,ax ; can't overflow
124 cmp bx,cx
125 mov bx,offset msg_malloc
126 jb puts
127 add [_heap_top],cx ; _BEG has zero'd heap
128 ;mov bx,ax
129 @@zalloc:
130 ;mov [byte bx],0
131 ;inc bx ; ZF=0
132 ;loop @@zalloc
133 ret
135 endp _malloc
138 ;***************************************************************
139 ;void puts(const char* s):
140 ;***************************************************************
141 global _puts:near
142 proc _puts near
144 pop ax ;caller return address
145 pop bx ; s
146 push bx
147 push ax
148 global puts:near ; puts(bx)
149 puts:
150 call putsz
151 mov bx,offset msg_crlf
153 global putsz:near ; putsz(bx)
154 putsz:
155 push bx
156 call strlen
157 pop dx
158 xchg ax,cx
159 mov bx,1
160 mov ah,40h
161 int 21h
162 xor ax,ax ; ZF=1 (for malloc failure)
163 ret
165 endp _puts
168 ;***************************************************************
169 ;int fileattr(const char* name);
170 ;***************************************************************
171 global _fileattr:near
172 proc _fileattr near
174 pop ax ;caller return address
175 pop dx ; name
176 push dx
177 push ax
178 mov ax,4300h
179 int 21h
180 xchg ax,cx
181 jmp chkc
183 endp _fileattr
186 ;***************************************************************
187 ;int open(const char* name, int flags=O_RDONLY);
188 ;***************************************************************
189 global _open:near
190 proc _open near
192 pop ax ;caller return address
193 pop bx ; name
194 push bx
195 push ax
196 global open:near ; open(bx)
197 open:
198 mov dx,bx
199 mov ax,3d00h
200 dos:
201 int 21h
202 chkc:
203 jnc doret
204 fail:
205 sbb ax,ax ; ax=-1 CF
206 cwd
207 doret:
208 ifndef NO386
209 push dx ; see next_chunk:lseek
210 push ax
211 pop eax
212 endif
213 ret
215 endp _open
218 ;***************************************************************
219 ;int close(int fd);
220 ;***************************************************************
221 global _close:near
222 proc _close near
224 pop ax ;caller return address
225 pop bx ; fd
226 push bx
227 push ax
228 global close:near ; close(bx)
229 close:
230 mov ah,3Eh
231 or bx,bx
232 jnz dos
233 ret
235 endp _close
238 ;***************************************************************
239 ;int read(int fd, void* data, int sz);
240 ;int write(int fd, const void* data, int sz);
241 ;***************************************************************
242 global _read:near
243 proc _read near
245 stc
246 db 0B0h ; mov al,im
247 global _write:near
248 clc
249 pop ax ;caller return address
250 pop bx ; fd
251 pop dx ; data
252 pop cx ; sz
253 push cx
254 push dx
255 push bx
256 push ax
257 mov ah,40h
258 sbb ah,0
259 jcxz fail
260 jmp dos
262 endp _read
264 ;***************************************************************
265 ;long lseekset(int fd, unsigned long sz);
266 ;***************************************************************
268 global _lseekset:near
269 proc _lseekset near
271 pop ax ;caller return address
272 pop bx ; fd
273 pop dx ; sz lo
274 pop cx ; sz hi
275 push cx
276 push bx
277 push ax
278 global lseekset:near
279 lseekset:
280 clc
281 db 0B0h ; mov al,im
282 global rewind:near
283 rewind: ; rewind(bx)
284 stc
285 mov ax,4200h
286 jnc dos
287 lseek0: ; lseek0(bx,ax=dir)
288 cwd
289 xor cx,cx
290 jmp dos
292 endp _lseekset
294 ifdef EXTRA
295 struc isostate ; struct isostate {
296 fd dw ? ; 0 int fd;
297 fileofs dd ? ; 2 unsigned long fileofs;
298 filesize dd ? ; 6 unsigned long filesize;
299 filemod dw ? ;10 unsigned short filemod;
300 filename dw ? ;12 char *filename;
301 dirofs dd ? ;14 unsigned long dirofs;
302 dirsize dd ? ;16 unsigned long dirsize;
303 curdirofs dd ? ;20 unsigned long curdirofs;
304 curdirsize dd ? ;24 unsigned long curdirsize;
305 curpos dd ? ;28 unsigned long curpos;
306 ends ; } isostate;
307 ;***************************************************************
308 ;unsigned long isolseek(const unsigned long *offset);
309 ;***************************************************************
310 global _isolseek:near
311 proc _isolseek near
313 pop ax
314 pop bx
315 push bx
316 push ax
317 mov dx,[bx]
318 mov cx,[bx+2]
319 extrn _isostate:isostate
320 mov bx,[_isostate.fd]
321 jmp lseekset ; (bx=fd, sz=cx:dx)
323 endp _isolseek
324 endif
327 ;***************************************************************
328 ;int strlen(const char* s);
329 ;***************************************************************
330 global _strlen:near
331 proc _strlen near
333 pop ax ;caller return address
334 pop bx ; s
335 push bx
336 push ax
337 global strlen:near ; strlen(bx)
338 strlen:
339 mov cx,bx
340 jcxz @@end
341 dec bx
342 @@lenlp:
343 inc bx
344 cmp [byte bx],0
345 jne @@lenlp
346 sub bx,cx
347 @@end:
348 xchg ax,bx
349 ret
351 endp _strlen
354 ;***************************************************************
355 ;int strhead(const char* a,const char* b);
356 ;***************************************************************
357 global _strhead:near
358 proc _strhead near
360 pop cx ;caller return address
361 pop bx ; a
362 pop ax ; b
363 push ax
364 push bx
365 push cx
366 @@loop:
367 xchg ax,bx
368 mov cl,[bx] ; cl = *b++
369 inc bx
370 or cl,cl ; clear C
371 jz fail ; return 0
372 xchg ax,bx
373 xor cl,[bx] ; cl -= *a++
374 inc bx
375 and cl,0dfh ; case insensitive
376 jz @@loop
377 ret ; return b (is not 0)
379 endp _strhead
382 ;***************************************************************
383 ;char* malloc_or_die(unsigned size);
384 ;***************************************************************
385 global _malloc_or_die:near
386 proc _malloc_or_die near
388 pop ax ;caller return address
389 pop cx ; size
390 push cx
391 push ax
392 global malloc_or_die:near ; malloc_or_die(cx)
393 malloc_or_die:
394 call malloc
395 jz _exit
396 ret
398 endp _malloc_or_die
401 ;***************************************************************
402 ;int die(const char* msg);
403 ;int exit();
404 ;int abort();
405 ;***************************************************************
406 global _die:near
407 proc _die near
409 pop ax ;caller return address
410 pop bx ; s
411 push bx
412 push ax
413 global die:near ; die(bx)
414 die:
415 call puts
416 global _exit:near
417 _exit:
418 mov al,[_no_exit]
419 cmp al,0
420 jne @@hang
421 extrn exit:near
422 inc ax
423 jmp near exit
424 @@hang:
425 mov bx, offset msg_hang
426 call puts
427 global _abort:near
428 _abort:
429 cli
430 @@stop:
431 hlt
432 jmp @@stop
434 endp _die
436 struc image_himem ;struct image_himem {
437 fd dw ? ; 0 int fd;
438 fallback dd ? ; 2 u32 fallback;
439 size dd ? ; 6 u32 size;
440 remaining dd ? ;10 u32 remaining;
441 buf dd ? ;14 u32 buf;
442 bufv dw ? ;18 u32 *bufv;
443 errmsg dw ? ;20 char *errmsg;
444 chunk_size dd ? ;22 u32 chunk_size;
445 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
446 state dw ? ;28 u16 state;
447 fd2close dw ? ;30 u16 fd2close;
448 ends ;};
450 ;***************************************************************
451 ;void next_chunk(struct image_himem *di);
452 ;***************************************************************
453 proc next_chunk near
455 push si
456 mov bx,[(image_himem di).fd]
457 call close
458 ifndef NO386
459 xor eax,eax
460 else
461 xor ax,ax
462 endif
463 cwd
464 mov [(image_himem di).fd],ax
465 mov bx,[(image_himem di).state]
466 cmp al,[bx] ; ""
467 jz @@end
468 mov si,bx
469 @@scan:
470 lodsb
471 mov cx,si
472 cmp al,','
473 jz @@eos
474 cmp al,0
475 jnz @@scan
476 dec cx
477 @@eos:
478 mov [(image_himem di).state],cx
479 dec si
480 push [word si]
481 mov [byte si],dl ; set temp eos
482 call open
483 pop [word si] ; restore string
484 jc @@die
485 mov [(image_himem di).fd],ax
486 mov [(image_himem di).fd2close],ax
487 xchg ax,bx
488 mov ax,4202h ; SEEK_END
489 call lseek0
490 @@die:
491 mov bx,[(image_himem di).errmsg]
492 jc die
493 mov bx,[(image_himem di).fd]
494 ifndef NO386
495 push eax
496 call rewind
497 pop eax
498 @@end:
499 mov [(image_himem di).chunk_size],eax
500 else
501 push ax
502 push dx
503 call rewind
504 pop dx
505 pop ax
506 @@end:
507 mov [word (image_himem di).chunk_size],ax
508 mov [word ((image_himem di).chunk_size)+2],dx
509 endif
510 pop si
511 ret
513 endp next_chunk
516 ifdef LARGE_IMAGES
517 struc data_himem ;struct data_himem {
518 first dd ? ; 0 u32 first;
519 cacheidx dw ? ; 4 int cacheidx;
520 pageidx dw ? ; 6 int pageidx;
521 cache dd 1024 dup(?) ; 8 int cache;
522 page dd 1024 dup(?) ;4104 int page;
523 ends ;}; // size=8200
524 endif
526 ;***************************************************************
527 ;u32* malloc_bufv_or_die(struct image_himem *m);
528 ;***************************************************************
529 global _malloc_bufv_or_die:near
530 proc _malloc_bufv_or_die near
532 p386
533 pop bx ;caller return address
534 pop ax
535 push ax
536 push bx
537 push si
538 xchg ax,si
539 ifdef LARGE_IMAGES
540 mov cx,[word ((image_himem si).size) + 2]
541 shr cx,4 ; pages index size = size >> 20
542 add cx,8+4096+8
543 call malloc_or_die
544 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
545 add ecx,[(image_himem si).size]
546 shr ecx,12
547 mov [curdata],ax
548 else
549 mov ecx,[(image_himem si).size]
550 dec ecx
551 shr ecx,12
552 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
553 push cx
554 inc cx ; cnt+1
555 shl cx,2 ; bufv => vcpi => vm86
556 ; our malloc zeroes allocated mem: bufv[cnt]=0;
557 ; Allocate pages, storing addrs in addrbuf
558 call malloc_or_die
559 pop cx
560 push ax
561 endif
562 mov [(image_himem si).bufv],ax
563 xchg ax,si
564 @@vcpi_alloc:
565 xor edx,edx
566 mov ax,0DE04h
567 int 67h
568 or ah,ah
569 mov bx,offset vcpi_alloc_err
570 jnz die
571 ; for (i = cnt-1; i >= 0; i--)
572 ifdef LARGE_IMAGES
573 mov eax,ecx
574 dec eax
575 else
576 mov ax,cx
577 dec ax
578 cwde
579 endif
580 shl eax,12 ; i*_4k
581 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
582 extrn _imgs
583 mov bx,offset _imgs+2
584 push eax
585 add eax,[bx-2+2]
586 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
587 pop eax ; i*_4k
588 jbe @@pmok
589 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
590 jae @@vcpi_alloc
591 @@pmok:
592 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
593 extrn _imgs
594 mov bx,offset _imgs+32+2
595 add eax,[bx-2+2] ; +initrd.fallback
596 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
597 ja @@initrdok
598 mov eax,[bx-2+6] ; initrd.size
599 add eax,[bx-2+2] ; +initrd.fallback
600 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
601 @@jnc_vcpi_alloc:
602 ja @@vcpi_alloc
603 @@initrdok:
604 ifdef LARGE_IMAGES
605 cmp [(data_himem si).first],0
606 jne @@notfirst
607 mov [(data_himem si).first],edx
608 @@notfirst:
609 mov bx,[(data_himem si).cacheidx]
610 cmp bh,4
611 jae @@nextpage
612 shl bx,2
613 inc [(data_himem si).cacheidx]
614 mov [(data_himem bx+si).cache],edx
615 loopd @@vcpi_alloc
616 mov [(data_himem bx+si).cache],ecx ; last is 0
617 @@nextpage:
618 and [(data_himem si).cacheidx],0
619 mov bx,[(data_himem si).pageidx]
620 mov [(data_himem bx+si).page],edx
621 add [(data_himem si).pageidx],4
622 push cx
623 lea cx,[(data_himem si).cache]
624 ifdef NO386
625 push edx
626 pop dx
627 pop ax
628 endif
629 call storepage ; storepage(edx,cx)
630 pop cx
631 or ecx,ecx ; clear C
632 jnz @@jnc_vcpi_alloc
633 mov [dword (data_himem si).cacheidx],ecx
634 xchg ax,si
635 else
636 mov [si],edx
637 lodsd ; si=+4
638 loop @@vcpi_alloc
639 pop ax
640 endif
641 pop si
642 ret
643 ifdef NO386
644 p8086
645 endif
647 endp _malloc_bufv_or_die
650 ;***************************************************************
651 ; void memcpy_image(struct image_himem *m);
652 ;***************************************************************
653 global _memcpy_image:near
654 proc _memcpy_image near
656 pop ax ;caller return address
657 pop bx
658 push bx
659 push ax
660 ifndef NO386
661 mov edx,[(image_himem bx).fallback]
662 mov eax,[(image_himem bx).buf]
663 cmp eax,edx ; if (m->fallback != m->buf)
664 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
665 ifdef LARGE_IMAGES
666 mov ecx,[(image_himem bx).size]
667 memcpy_imagez:
668 push ecx
669 else
670 push [(image_himem bx).size]
671 endif
672 push eax
673 push 0
674 call_memcpy32:
675 push edx
676 else
677 mov ax,[word ((image_himem bx).fallback)]
678 mov dx,[word ((image_himem bx).fallback)+2]
679 mov cx,[word ((image_himem bx).buf)]
680 cmp ax,cx ; if (m->fallback != m->buf)
681 jnz @@do
682 cmp dx,[word ((image_himem bx).buf)+2]
683 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
684 @@do:
685 push [word ((image_himem bx).size)+2]
686 push [word ((image_himem bx).size)]
687 push [word ((image_himem bx).buf)+2]
688 push cx
689 xor cx,cx
690 push cx
691 call_memcpy32:
692 push dx
693 push ax
694 ifdef LARGE_IMAGES
695 jmp @@memcpy
696 memcpy_imagez:
697 p386
698 push ecx
699 push eax
700 push 0
701 push edx
702 ifdef NO386
703 p8086
704 endif
705 endif
706 endif
707 @@memcpy:
708 extrn _memcpy32:near
709 call near _memcpy32
710 add sp,14
711 @@skip:
712 ret
714 endp _memcpy_image
716 ;***************************************************************
717 ;void storepage(u32 *dst, u16 src);
718 ;***************************************************************
719 global _storepage:near
720 proc _storepage near
722 pop ax ;caller return address
723 pop bx
724 pop cx
725 push cx
726 push bx
727 push ax
728 ifndef NO386
729 mov edx,[bx]
730 else
731 mov ax,[bx]
732 mov dx,[bx+2]
733 endif
734 storepage:
735 ifndef NO386
736 push 0
737 push 4096
738 push 0
739 else
740 xor bx,bx
741 push bx
742 mov bh,4096/256
743 push bx
744 xor bx,bx
745 push bx
746 endif
747 push cx
748 push ds
749 jmp call_memcpy32
751 endp _storepage
754 ifdef LARGE_IMAGES
755 p386
756 ;***************************************************************
757 ;void reset_bufv(u32 *p);
758 ;***************************************************************
759 global _reset_bufv:near
760 proc _reset_bufv near
762 pop ax ;caller return address
763 pop bx
764 push bx
765 push ax
766 mov [curdata],bx
767 and [dword (data_himem bx).cacheidx],0
768 ret
770 endp _reset_bufv
772 ;***************************************************************
773 ;u32* prev_bufv();
774 ;u32* prev_bufv();
775 ;***************************************************************
776 global _prev_bufv:near
777 global _next_bufv:near
778 proc _prev_bufv near
780 stc
781 db 73h ; jnc
782 _next_bufv:
783 clc
784 sbb ax,ax
785 stc
786 rcl ax,1 ; -1/+1
787 xor ecx,ecx
788 push si
789 mov si,[curdata]
790 add ax,[(data_himem si).cacheidx]
791 test ax,0fc00h
792 jz @@gotpage
793 push ax ; FFFF / 0400
794 sar ax,8 ; FFFC / 0004
795 and al,0fch
796 add [(data_himem si).pageidx],ax
797 mov bx,[(data_himem si).pageidx]
798 lea bx,[(data_himem bx+si).page]
799 mov edx,ds
800 shl edx,4
801 lea cx,[(data_himem si).cache]
802 add edx,ecx
803 mov eax,[bx]
804 or eax,eax
805 jnz @@pageok
806 pop ax
807 xchg ax,bx
808 pop si
809 ret
810 @@pageok:
811 mov cx,4096
812 call memcpy_imagez ; get page
813 pop ax ; FFFF / 0400
814 cbw
815 shr ax,6 ; 03FF / 0000
816 @@gotpage:
817 mov [(data_himem si).cacheidx],ax
818 shl ax,2
819 xchg ax,bx
820 lea ax,[(data_himem bx+si).cache]
821 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
822 jnz @@notfirst2
823 xchg ax,si ; &first
824 @@notfirst2:
825 pop si
826 ret
827 ifdef NO386
828 p8086
829 endif
831 endp _prev_bufv
832 endif
835 ;***************************************************************
836 ;void open_image(const char *name, struct image_himem *m);
837 ;***************************************************************
838 global _open_image:near
839 proc _open_image near
841 arg fname :word, \
842 m :word = PARAM_SIZE
844 push bp
845 mov bp,sp
846 push si di
847 ifndef NO386
848 xor eax,eax ; 1st loop flag + eos
849 else
850 xor ax,ax ; 1st loop flag + eos
851 endif
852 mov di,[m]
853 cmp [(image_himem di).fd],ax
854 jnz @@alreadydone
855 ifndef NO386
856 mov [(image_himem di).size],eax ; m->size = 0L
857 else
858 mov [word (image_himem di).size],ax ; m->size = 0L
859 mov [word ((image_himem di).size)+2],ax
860 endif
861 mov [(image_himem di).next_chunk],offset next_chunk
862 mov si,[fname]
863 mov [(image_himem di).state],si
864 @@next:
865 push di
866 call [(image_himem di).next_chunk] ; m->next_chunk()
867 pop di
868 ifndef NO386
869 add eax,3
870 and al,0FCh
871 add [(image_himem di).size],eax ; m->size += m->chunk_size
872 or eax,eax
873 jnz @@next
874 else
875 mov cx,ax
876 or cx,dx
877 add ax,3
878 adc dx,0
879 and al,0FCh
880 add [word (image_himem di).size],ax ; m->size += m->chunk_size
881 adc [word ((image_himem di).size)+2],dx
882 inc cx ; jcxnz
883 loop @@next
884 endif
885 mov [(image_himem di).state],si
886 push di
887 call [(image_himem di).next_chunk] ; m->next_chunk()
888 pop di
889 @@alreadydone:
890 push ax
891 image_done:
892 pop ax
893 pop di si bp
894 ret
896 endp _open_image
899 ;***************************************************************
900 ;int read_image(struct image_himem *m, void* data, int sz);
901 ;***************************************************************
902 global _read_image:near
903 proc _read_image near
905 arg m :word, \
906 data :word, \
907 sz :word = PARAM_SIZE
909 push bp
910 mov bp,sp
911 push si di
912 ifndef NO386
913 push 0 ; return value
914 else
915 xor ax,ax
916 push ax
917 endif
918 mov di,[m]
919 @@loop:
920 ifndef NO386
921 xor ecx,ecx
922 mov cx,[word sz]
923 @@chksz:
924 mov eax,[(image_himem di).chunk_size]
925 cmp ecx,eax
926 jb @@szok
927 xchg eax,ecx
928 else
929 mov cx,[word sz]
930 @@chksz:
931 mov ax,[word (image_himem di).chunk_size]
932 cmp cx,ax
933 jb @@szok
934 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
935 jne @@szok
936 xchg ax,cx
937 endif
938 @@szok:
939 jcxz image_done
940 push cx
941 push [word data]
942 push [word di]
943 call _read
944 pop dx
945 pop bx
946 pop dx
947 jc image_done
948 add bx,ax
949 xor cx,cx
950 ifndef NO386
951 cwde ; ax < 8000h
952 sub [(image_himem di).chunk_size],eax
953 else
954 cwd ; ax < 8000h
955 sub [word (image_himem di).chunk_size],ax
956 sbb [word ((image_himem di).chunk_size)+2],dx
957 jnz @@fill
958 cmp [word (image_himem di).chunk_size],dx
959 endif
960 jnz @@fill
961 dec cx
962 @@fill:
963 test al,3
964 je @@filled
965 mov [bx],dl
966 inc bx
967 inc ax
968 jmp @@fill
969 @@filled:
970 ifndef NO386
971 sub [(image_himem di).remaining],eax
972 else
973 sub [word (image_himem di).remaining],ax
974 sbb [word ((image_himem di).remaining)+2],dx
975 endif
976 add [bp-4-2],ax
977 add [word data],ax
978 sub [word sz],ax
979 pushf
980 and cx,[(image_himem di).next_chunk]
981 jz @@same_chunk
982 push di
983 call cx ; m->next_chunk()
984 pop di
985 @@same_chunk:
986 popf
987 jnz @@loop
988 jmp image_done
990 endp _read_image
993 ;***************************************************************
994 ;unsigned long strtol(const char *s);
995 ;***************************************************************
996 global _strtol:near
997 proc _strtol near
999 ifndef NO386
1000 pop ax ;caller return address
1001 pop cx ; s
1002 push cx
1003 push ax
1004 xor ebx,ebx
1005 push si
1006 jcxz @@end
1007 mov si,cx
1008 xor ecx,ecx
1009 xor eax,eax
1010 lodsb
1011 mov dx,ax
1012 or al,20h
1013 cmp al,'n' ; vga=normal
1014 je @@vga
1015 dec cx
1016 cmp al,'e' ; vga=extended
1017 je @@vga
1018 dec cx
1019 cmp al,'a' ; vga=ask
1020 jne @@notvga
1021 @@vga:
1022 dec cx
1023 xchg ax,cx
1024 cwd
1025 jmp @@popsiret
1026 @@notvga:
1027 mov cx,10 ; radix
1028 xchg ax,dx
1029 cmp al,'+'
1030 je @@radixskip
1031 cmp al,'-'
1032 clc
1033 jne @@radixkeep
1034 stc
1035 @@radixskip:
1036 lodsb
1037 @@radixkeep:
1038 pushf
1039 cmp al,'0'
1040 jne @@radixok
1041 mov cl,8
1042 lodsb
1043 or al,20h
1044 cmp al,'x'
1045 jne @@radixok
1046 mov cl,16
1047 @@strtollp:
1048 lodsb
1049 @@radixok:
1050 or al,20h
1051 sub al,'0'
1052 jb @@endstrtol
1053 cmp al,9
1054 jbe @@digitok
1055 cmp al,'a'-'0'
1056 jb @@endstrtol
1057 sub al,'a'-'0'-10
1058 @@digitok:
1059 cmp al,cl
1060 jae @@endstrtol
1061 xchg eax,ebx
1062 mul ecx
1063 add eax,ebx
1064 xchg eax,ebx
1065 jmp @@strtollp
1066 @@endstrtol:
1067 mov cl,10
1068 cmp al,'k'-'a'+10
1069 je @@shift
1070 mov cl,20
1071 cmp al,'m'-'a'+10
1072 je @@shift
1073 mov cl,30
1074 cmp al,'g'-'a'+10
1075 jne @@noshift
1076 @@shift:
1077 shl ebx,cl
1078 @@noshift:
1079 popf
1080 jnc @@end
1081 neg ebx
1082 @@end:
1083 push ebx
1084 pop ax
1085 pop dx
1086 @@popsiret:
1087 pop si
1088 else
1089 pop ax ;caller return address
1090 pop cx ; s
1091 push cx
1092 push ax
1093 push si
1094 push di
1095 xor ax,ax
1096 cwd
1097 jcxz @@goend
1098 xchg ax,di
1099 mov si,cx
1100 lodsb
1101 mov bx,ax
1102 or al,20h
1103 mov cx,-1
1104 cmp al,'n' ; vga=normal
1105 je @@vga
1106 dec cx
1107 cmp al,'e' ; vga=extended
1108 je @@vga
1109 dec cx
1110 cmp al,'a' ; vga=ask
1111 jne @@notvga
1112 @@vga:
1113 xchg ax,cx
1114 @@goend:
1115 jmp @@popdisiret
1116 @@notvga:
1117 mov cx,10 ; radix
1118 xchg ax,bx
1119 cmp al,'+'
1120 je @@radixskip
1121 cmp al,'-'
1122 clc
1123 jne @@radixkeep
1124 stc
1125 @@radixskip:
1126 lodsb
1127 @@radixkeep:
1128 pushf
1129 cmp al,'0'
1130 jne @@radixok
1131 mov cl,8
1132 lodsb
1133 mov al,20h
1134 cmp al,'x'
1135 jne @@radixok
1136 mov cl,16
1137 @@strtollp:
1138 lodsb
1139 @@radixok:
1140 or al,20h
1141 sub al,'0'
1142 jb @@endstrtol
1143 cmp al,9
1144 jbe @@digitok
1145 cmp al,'a'-'0'
1146 jb @@endstrtol
1147 sub al,'a'-'0'-10
1148 @@digitok:
1149 cmp al,cl
1150 jae @@endstrtol
1152 push ax
1153 push si
1154 push dx
1155 xchg ax,di
1156 mul cx
1157 xchg ax,di
1158 xchg ax,dx
1159 xchg ax,si
1160 pop ax
1161 mul cx
1162 add ax,si
1163 pop si
1164 xchg ax,dx
1165 pop ax
1166 mov ah,0
1167 add di,ax
1168 adc dx,0
1170 jmp @@strtollp
1171 @@endstrtol:
1172 mov cl,10
1173 cmp al,'k'-'a'+10
1174 je @@shift
1175 mov cl,20
1176 cmp al,'m'-'a'+10
1177 je @@shift
1178 mov cl,30
1179 cmp al,'g'-'a'+10
1180 jne @@noshift
1181 @@shift:
1182 rcl di,1
1183 shl dx,1
1184 loop @@shift
1185 @@noshift:
1186 popf
1187 jnc @@end
1188 not dx
1189 neg di
1190 jne @@end
1191 inc dx
1192 @@end:
1193 xchg ax,di
1194 @@popdisiret:
1195 pop di
1196 pop si
1197 endif
1198 ret
1200 endp _strtol
1203 ifdef NO386
1204 ;***************************************************************
1205 ;u16 topseg();
1206 ;***************************************************************
1207 global _topseg:near
1208 proc _topseg near
1210 int 12h
1211 jnc @@max640k
1212 mov ax,640 ; 9000
1213 @@max640k:
1214 dec ax
1215 and al,0C0h
1216 mov cl,6
1217 shl ax,cl
1218 ret
1220 endp _topseg
1221 endif
1223 ifdef EXTRA
1224 p8086
1226 ;***************************************************************
1227 ;int strcmp(const char* a,const char* b);
1228 ;***************************************************************
1229 global _strcmp:near
1230 proc _strcmp near
1232 pop cx ;caller return address
1233 pop bx ; a
1234 pop ax ; b
1235 push ax
1236 push bx
1237 push cx
1238 push si
1239 xchg ax,si
1240 sub bx,si
1241 @@lp:
1242 mov al,[si]
1243 sub al,[bx+si]
1244 jnz @@out
1245 lodsb
1246 cmp al,0
1247 jne @@lp
1248 @@out:
1249 cbw
1250 pop si
1251 ret
1253 endp _strcmp
1256 ;***************************************************************
1257 ;char strstr(const char* a,const char* b);
1258 ;***************************************************************
1259 global _strstr:near
1260 proc _strstr near
1262 pop ax ;caller return address
1263 pop cx ; a
1264 pop dx ; b
1265 push dx
1266 push cx
1267 push ax
1268 push si
1269 @@loop:
1270 xor ax,ax
1271 mov si,cx
1272 cmp [si],al ; *a
1273 jz @@end ; return ax = NULL
1274 mov bx,dx
1275 sub bx,si
1276 @@match:
1277 or ah,[bx+si] ; *b
1278 jz @@found
1279 lodsb
1280 sub ah,al
1281 jz @@match
1282 inc cx
1283 jmp @@loop
1284 @@found:
1285 xchg ax,cx
1286 @@end:
1287 pop si
1288 ret
1290 endp _strstr
1293 ;***************************************************************
1294 ;char *progname(void)
1295 ;***************************************************************
1296 global _progname:near
1297 proc _progname near
1299 push si di es
1300 mov ah,30h
1301 int 21h
1302 xor di,di
1303 cmp al,3
1304 mov ax,di
1305 jb @@skip
1306 ;mov es,[cs:2Ch]
1307 mov es,[di+2Ch]
1308 mov cx,-1
1309 @@loop:
1310 repne
1311 scasb
1312 scasb
1313 jne @@loop
1314 inc di
1315 inc di
1316 mov si,di ; progname @es:di
1317 repne
1318 scasb
1319 mov cx,di
1320 sub cx,si ; progname len
1321 call malloc_or_die ; keep cx
1322 mov di,ax
1323 push ds
1324 push es
1325 pop ds
1326 pop es
1327 rep
1328 movsb
1329 push es
1330 pop ds
1331 @@skip:
1332 pop es di si
1333 ret
1335 endp _progname
1338 ;***************************************************************
1339 ;void chdirname(char *path)
1340 ;***************************************************************
1341 global _chdirname:near
1342 proc _chdirname near
1344 pop ax
1345 pop bx
1346 push bx
1347 push ax
1349 cmp [byte bx+1],3Ah
1350 jne @@nodisk
1351 mov dl,20h
1352 or dl,[bx]
1353 sub dl,61h
1354 mov ah,0Eh
1355 int 21h
1356 inc bx
1357 inc bx
1358 @@nodisk:
1359 xor cx,cx
1360 @@next:
1361 mov al,[bx]
1362 cmp al,5Ch
1363 jne @@tsteos
1364 mov dx,bx
1365 inc cx
1366 @@tsteos:
1367 inc bx
1368 or al,al
1369 jnz @@next
1370 jcxz @@end
1371 mov bx,dx
1372 push [word bx]
1373 mov [bx],al
1374 stc
1375 mov ax,713Bh ; chdir long filename
1376 int 21h
1377 mov ah,3Bh ; chdir
1378 jnc chdirdone
1379 int 21h
1380 chdirdone:
1381 pop [word bx]
1382 @@end:
1383 ret
1385 endp _chdirname
1388 ;***************************************************************
1389 ;char *ultoa(unsigned long n);
1390 ;***************************************************************
1391 global _ultoa:near
1392 proc _ultoa near
1394 pop ax
1395 pop cx
1396 pop dx
1397 push dx
1398 push cx
1399 push ax ; DX:CX = n
1400 push si
1401 mov si,10
1402 mov bx,offset ultoabuf+11
1403 @@loop:
1404 dec bx
1405 xchg ax,dx
1406 xor dx,dx
1407 div si ; DX:AX = 0000:hi(n)
1408 xchg ax,cx ; CX = hi(n)/10
1409 div si ; DX:AX = hi(n)%10:lo(n)
1410 xchg ax,cx ; CX = lo(n/10)
1411 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1412 add al,'0'
1413 mov [bx],al
1414 mov ax,cx
1415 or ax,dx
1416 jnz @@loop
1417 xchg ax,bx
1418 pop si
1419 ret
1421 endp _ultoa
1424 ;***************************************************************
1425 ;unsigned long kver2ul(char *kernel_version);
1426 ;***************************************************************
1427 global _kver2ul:near
1428 proc _kver2ul near
1430 pop bx
1431 pop ax
1432 push ax
1433 push bx
1434 push bp si di
1435 xchg ax,si
1436 xor di,di
1437 push di
1438 push di
1439 mov bp,sp
1440 inc di
1441 inc di
1442 mov cl,4
1443 @@number:
1444 xor ax,ax
1445 @@digit:
1446 shl al,cl
1447 shl ax,cl
1448 lodsb
1449 sub al,30h
1450 cmp al,9
1451 jbe @@digit
1452 mov [bp+di],ah
1453 dec di
1454 jns @@number
1455 pop ax
1456 pop dx
1457 pop di si bp
1458 kver2ulret:
1459 ret
1461 endp _kver2ul
1464 ;***************************************************************
1465 ;void try_default_args();
1466 ;***************************************************************
1467 global _try_default_args:near
1468 proc _try_default_args near
1470 mov bx,offset tazboot_cmd
1471 call open
1472 jc kver2ulret
1473 mov cx,4096
1474 mov di,[_heap_top]
1475 push cx
1476 extrn read_cmdline:near
1477 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1479 endp _try_default_args
1481 endif
1483 ends _TEXT
1485 end
1487 ;###### END OF FILE ############################################