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

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