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

linld: fix memcpy32 (16 low mem case)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Oct 23 08:25:49 2018 +0200 (2018-10-23)
parents 81a3d87e0965
children 049ced0bd387
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 cwd
486 endif
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],ah ; 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 cx ;caller return address
865 pop bx ; name
866 pop ax ; m
867 push ax
868 push bx
869 push cx
870 push di
871 xchg ax,di
872 mov [(image_himem di).next_chunk],offset next_chunk
873 mov [(image_himem di).state],bx
874 push bx
875 @@next:
876 call [(image_himem di).next_chunk] ; m->next_chunk()
877 ifndef NO386
878 add eax,3
879 and al,0FCh
880 add [(image_himem di).size],eax ; m->size += m->chunk_size
881 or eax,eax
882 jnz @@next
883 else
884 mov cx,ax
885 or cx,dx
886 add ax,3
887 adc dx,0
888 and al,0FCh
889 add [word (image_himem di).size],ax ; m->size += m->chunk_size
890 adc [word ((image_himem di).size)+2],dx
891 inc cx ; jcxnz
892 loop @@next
893 endif
894 pop [(image_himem di).state]
895 call [(image_himem di).next_chunk] ; m->next_chunk()
896 pop di
897 ret
899 endp _open_image
902 ;***************************************************************
903 ;int read_image(struct image_himem *m, char* data, int sz);
904 ;***************************************************************
905 global _read_image:near
906 proc _read_image near
908 arg m :word, \
909 data :word, \
910 sz :word = PARAM_SIZE
912 push bp
913 mov bp,sp
914 push di
915 ifndef NO386
916 push 0 ; return value
917 else
918 xor ax,ax
919 push ax
920 endif
921 mov di,[m]
922 @@loop:
923 ifndef NO386
924 movzx ecx,[word sz]
925 mov eax,[(image_himem di).chunk_size]
926 cmp ecx,eax
927 jb @@szok
928 else
929 mov cx,[word sz]
930 mov ax,[word (image_himem di).chunk_size]
931 cmp cx,ax
932 jb @@szok
933 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
934 jne @@szok
935 endif
936 xchg ax,cx
937 @@szok:
938 jcxz image_done
939 push cx
940 push [word data]
941 push [word di]
942 call _read
943 pop dx
944 pop bx
945 pop cx
946 jc image_done
947 add bx,ax
948 xor cx,cx
949 ifndef NO386
950 cwde ; ax < 8000h
951 sub [(image_himem di).chunk_size],eax
952 else
953 cwd ; ax < 8000h
954 sub [word (image_himem di).chunk_size],ax
955 sbb [word ((image_himem di).chunk_size)+2],dx
956 jnz @@fill
957 cmp [word (image_himem di).chunk_size],dx
958 endif
959 jnz @@fill
960 dec cx
961 @@fill:
962 test al,3
963 je @@filled
964 mov [bx],dh
965 inc bx
966 inc ax
967 jmp @@fill
968 @@filled:
969 ifndef NO386
970 sub [(image_himem di).remaining],eax
971 else
972 sub [word (image_himem di).remaining],ax
973 sbb [word ((image_himem di).remaining)+2],dx
974 endif
975 add [bp-2-2],ax
976 add [word data],ax
977 sub [word sz],ax
978 pushf
979 jcxz @@same_chunk
980 call [(image_himem di).next_chunk]
981 @@same_chunk:
982 popf
983 jnz @@loop
984 image_done:
985 pop ax
986 pop di bp
987 ret
989 endp _read_image
992 ;***************************************************************
993 ;unsigned long strtol(const char *s);
994 ;***************************************************************
995 global _strtol:near
996 proc _strtol near
998 ifndef NO386
999 pop ax ;caller return address
1000 pop cx ; s
1001 push cx
1002 push ax
1003 xor ebx,ebx
1004 push si
1005 jcxz @@end
1006 mov si,cx
1007 xor ecx,ecx
1008 xor eax,eax
1009 lodsb
1010 mov dx,ax
1011 or al,20h
1012 cmp al,'n' ; vga=normal
1013 je @@vga
1014 dec cx
1015 cmp al,'e' ; vga=extended
1016 je @@vga
1017 dec cx
1018 cmp al,'a' ; vga=ask
1019 jne @@notvga
1020 @@vga:
1021 dec cx
1022 xchg ax,cx
1023 cwd
1024 jmp @@popsiret
1025 @@notvga:
1026 mov cx,10 ; radix
1027 xchg ax,dx
1028 cmp al,'+'
1029 je @@radixskip
1030 cmp al,'-'
1031 clc
1032 jne @@radixkeep
1033 stc
1034 @@radixskip:
1035 lodsb
1036 @@radixkeep:
1037 pushf
1038 cmp al,'0'
1039 jne @@radixok
1040 mov cl,8
1041 lodsb
1042 or al,20h
1043 cmp al,'x'
1044 jne @@radixok
1045 mov cl,16
1046 @@strtollp:
1047 lodsb
1048 @@radixok:
1049 or al,20h
1050 sub al,'0'
1051 jb @@endstrtol
1052 cmp al,9
1053 jbe @@digitok
1054 cmp al,'a'-'0'
1055 jb @@endstrtol
1056 sub al,'a'-'0'-10
1057 @@digitok:
1058 cmp al,cl
1059 jae @@endstrtol
1060 xchg eax,ebx
1061 mul ecx
1062 add eax,ebx
1063 xchg eax,ebx
1064 jmp @@strtollp
1065 @@endstrtol:
1066 mov cl,10
1067 cmp al,'k'-'a'+10
1068 je @@shift
1069 mov cl,20
1070 cmp al,'m'-'a'+10
1071 je @@shift
1072 mov cl,30
1073 cmp al,'g'-'a'+10
1074 jne @@noshift
1075 @@shift:
1076 shl ebx,cl
1077 @@noshift:
1078 popf
1079 jnc @@end
1080 neg ebx
1081 @@end:
1082 push ebx
1083 pop ax
1084 pop dx
1085 @@popsiret:
1086 pop si
1087 else
1088 pop ax ;caller return address
1089 pop cx ; s
1090 push cx
1091 push ax
1092 push si
1093 push di
1094 xor ax,ax
1095 cwd
1096 jcxz @@goend
1097 xchg ax,di
1098 mov si,cx
1099 lodsb
1100 mov bx,ax
1101 or al,20h
1102 mov cx,-1
1103 cmp al,'n' ; vga=normal
1104 je @@vga
1105 dec cx
1106 cmp al,'e' ; vga=extended
1107 je @@vga
1108 dec cx
1109 cmp al,'a' ; vga=ask
1110 jne @@notvga
1111 @@vga:
1112 xchg ax,cx
1113 @@goend:
1114 jmp @@popdisiret
1115 @@notvga:
1116 mov cx,10 ; radix
1117 xchg ax,bx
1118 cmp al,'+'
1119 je @@radixskip
1120 cmp al,'-'
1121 clc
1122 jne @@radixkeep
1123 stc
1124 @@radixskip:
1125 lodsb
1126 @@radixkeep:
1127 pushf
1128 cmp al,'0'
1129 jne @@radixok
1130 mov cl,8
1131 lodsb
1132 or al,20h
1133 cmp al,'x'
1134 jne @@radixok
1135 mov cl,16
1136 @@strtollp:
1137 lodsb
1138 @@radixok:
1139 or al,20h
1140 sub al,'0'
1141 jb @@endstrtol
1142 cmp al,9
1143 jbe @@digitok
1144 cmp al,'a'-'0'
1145 jb @@endstrtol
1146 sub al,'a'-'0'-10
1147 @@digitok:
1148 cmp al,cl
1149 jae @@endstrtol
1151 push ax
1152 push si
1153 push dx
1154 xchg ax,di
1155 mul cx
1156 xchg ax,di
1157 xchg ax,dx
1158 xchg ax,si
1159 pop ax
1160 mul cx
1161 add ax,si
1162 pop si
1163 xchg ax,dx
1164 pop ax
1165 mov ah,0
1166 add di,ax
1167 adc dx,0
1169 jmp @@strtollp
1170 @@endstrtol:
1171 mov cl,10
1172 cmp al,'k'-'a'+10
1173 je @@shift
1174 mov cl,20
1175 cmp al,'m'-'a'+10
1176 je @@shift
1177 mov cl,30
1178 cmp al,'g'-'a'+10
1179 jne @@noshift
1180 @@shift:
1181 rcl di,1
1182 shl dx,1
1183 loop @@shift
1184 @@noshift:
1185 popf
1186 jnc @@end
1187 not dx
1188 neg di
1189 jne @@end
1190 inc dx
1191 @@end:
1192 xchg ax,di
1193 @@popdisiret:
1194 pop di
1195 pop si
1196 endif
1197 ret
1199 endp _strtol
1202 ifdef NO386
1203 ;***************************************************************
1204 ;u16 topseg();
1205 ;***************************************************************
1206 global _topseg:near
1207 proc _topseg near
1209 int 12h
1210 jnc @@max640k
1211 mov ax,640 ; 9000
1212 @@max640k:
1213 dec ax
1214 and al,0C0h
1215 mov cl,6
1216 shl ax,cl
1217 ret
1219 endp _topseg
1220 endif
1222 ifdef EXTRA
1223 p8086
1224 ;***************************************************************
1225 ;char *progname(void)
1226 ;***************************************************************
1227 global _progname:near
1228 proc _progname near
1230 push si di es
1231 mov ah,30h
1232 int 21h
1233 xor di,di
1234 cmp al,3
1235 mov ax,di
1236 jb @@skip
1237 ;mov es,[cs:2Ch]
1238 mov es,[di+2Ch]
1239 mov cx,sp ; big enough
1240 @@loop:
1241 repne
1242 scasb
1243 scasb
1244 jne @@loop
1245 inc di
1246 inc di
1247 mov si,di ; progname @es:di
1248 repne
1249 scasb
1250 mov cx,di
1251 sub cx,si ; progname len
1252 call malloc_or_die ; keep cx
1253 mov di,ax
1254 push ds
1255 push es
1256 pop ds
1257 pop es
1258 rep
1259 movsb
1260 push es
1261 pop ds
1262 @@skip:
1263 pop es di si
1264 ret
1266 endp _progname
1269 ;***************************************************************
1270 ;void chdirname(char *path)
1271 ;***************************************************************
1272 global _chdirname:near
1273 proc _chdirname near
1275 pop ax
1276 pop bx
1277 push bx
1278 push ax
1280 cmp [byte bx+1],3Ah ; ':'
1281 jne @@nodisk
1282 mov dl,20h
1283 or dl,[bx]
1284 sub dl,61h
1285 mov ah,0Eh
1286 int 21h
1287 inc bx
1288 inc bx
1289 @@nodisk:
1290 xor cx,cx
1291 @@next:
1292 mov al,[bx]
1293 cmp al,5Ch
1294 jne @@tsteos
1295 mov dx,bx
1296 inc cx
1297 @@tsteos:
1298 inc bx
1299 or al,al
1300 jnz @@next
1301 jcxz @@end
1302 mov bx,dx
1303 push [word bx]
1304 mov [bx],al
1305 stc
1306 mov ax,713Bh ; chdir long filename (ds:dx)
1307 int 21h
1308 mov ah,3Bh ; chdir(ds:dx)
1309 jnc chdirdone
1310 int 21h
1311 chdirdone:
1312 pop [word bx]
1313 @@end:
1314 ret
1316 endp _chdirname
1319 ;***************************************************************
1320 ;char *ultoa(unsigned long n);
1321 ;***************************************************************
1322 global _ultoa:near
1323 proc _ultoa near
1325 pop ax
1326 pop cx
1327 pop dx
1328 push dx
1329 push cx
1330 push ax ; DX:CX = n
1331 push si
1332 mov si,10
1333 mov bx,offset ultoabuf+11
1334 @@loop:
1335 dec bx
1336 xchg ax,dx
1337 xor dx,dx
1338 div si ; DX:AX = 0000:hi(n)
1339 xchg ax,cx ; CX = hi(n)/10
1340 div si ; DX:AX = hi(n)%10:lo(n)
1341 xchg ax,cx ; CX = lo(n/10)
1342 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1343 add al,'0'
1344 mov [bx],al
1345 mov ax,cx
1346 or ax,dx
1347 jnz @@loop
1348 xchg ax,bx
1349 pop si
1350 ret
1352 endp _ultoa
1355 ;***************************************************************
1356 ;unsigned long kver2ul(char *kernel_version);
1357 ;***************************************************************
1358 global _kver2ul:near
1359 proc _kver2ul near
1361 pop bx
1362 pop ax
1363 push ax
1364 push bx
1365 push si
1366 xchg ax,si
1367 xor bx,bx
1368 mov cx,304h
1369 @@number:
1370 xor ax,ax
1371 cwd
1372 @@digit:
1373 shl al,cl
1374 shl ax,cl
1375 lodsb
1376 sub al,30h
1377 cmp al,9
1378 jbe @@digit
1379 mov dl,bh
1380 mov bh,bl
1381 mov bl,ah
1382 dec ch
1383 jnz @@number
1384 xchg ax,bx
1385 pop si
1386 kver2ulret:
1387 ret
1389 endp _kver2ul
1392 ;***************************************************************
1393 ;void try_default_args();
1394 ;***************************************************************
1395 global _try_default_args:near
1396 proc _try_default_args near
1398 mov bx,offset tazboot_cmd
1399 call open
1400 jc kver2ulret
1401 mov cx,4096
1402 mov di,[_heap_top]
1403 push cx
1404 extrn read_cmdline:near
1405 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1407 endp _try_default_args
1409 endif
1411 ends _TEXT
1413 end
1415 ;###### END OF FILE ############################################