wok view linld/stuff/src/CRTL.ASM @ rev 19882
bluez: add SIM access profile support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Mon Apr 03 10:59:15 2017 +0200 (2017-04-03) |
parents | 766a40e6c5e0 |
children | 9e8f9b54bd83 |
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 dl,3
59 db 0bbh ; mov bx,imm opcode
60 global _strcat:near
61 _strcat:
62 mov dl,1
63 db 0bbh ; mov bx,imm opcode
64 global _strcpy:near
65 _strcpy:
66 mov dl,0
67 endif
68 pop ax ;caller return address
69 pop cx ; a
70 pop bx ; b
71 push bx
72 push cx
73 push ax
74 push si
75 mov si,cx
76 ifdef EXTRA
77 shr dl,1
78 jnc @@nocat
79 endif
80 @@catlp:
81 lodsb
82 cmp al,0
83 jne @@catlp
84 dec si
85 ifdef EXTRA
86 shr dl,1
87 jnc @@nocat
88 endif
89 cmp cx,si
90 jz @@nocat
91 mov [word si],20h
92 inc si
93 @@nocat:
94 sub bx,si
95 @@cpylp:
96 mov al,[bx+si]
97 mov [si],al
98 inc si
99 cmp al,0
100 jne @@cpylp
101 mov ax,cx
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 ifdef EXTRA
265 ;***************************************************************
266 ;long lseekset(int fd, unsigned long sz);
267 ;***************************************************************
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 dx
278 else
279 ;***************************************************************
280 ;long seekset(int fd, unsigned sz);
281 ;***************************************************************
282 global _seekset:near
283 proc _seekset near
285 xor cx,cx
286 pop ax ;caller return address
287 pop bx ; fd
288 pop dx ; sz
289 push dx
290 endif
292 push bx
293 push ax
294 global lseekset:near
295 lseekset:
296 clc
297 db 0B0h ; mov al,im
298 global rewind:near
299 rewind: ; rewind(bx)
300 stc
301 mov ax,4200h
302 jnc dos
303 lseek0: ; lseek0(bx,ax=dir)
304 cwd
305 xor cx,cx
306 jmp dos
308 ifdef EXTRA
309 endp _lseekset
310 else
311 endp _seekset
312 endif
314 ifdef EXTRA
315 struc isostate ; struct isostate {
316 fd dw ? ; 0 int fd;
317 fileofs dd ? ; 2 unsigned long fileofs;
318 filesize dd ? ; 6 unsigned long filesize;
319 filemod dw ? ;10 unsigned short filemod;
320 filename dw ? ;12 char *filename;
321 dirofs dd ? ;14 unsigned long dirofs;
322 dirsize dd ? ;16 unsigned long dirsize;
323 curdirofs dd ? ;20 unsigned long curdirofs;
324 curdirsize dd ? ;24 unsigned long curdirsize;
325 curpos dd ? ;28 unsigned long curpos;
326 ends ; } isostate;
327 ;***************************************************************
328 ;unsigned long isolseek(const unsigned long *offset);
329 ;***************************************************************
330 global _isolseek:near
331 proc _isolseek near
333 pop ax
334 pop bx
335 push bx
336 push ax
337 mov dx,[bx]
338 mov cx,[bx+2]
339 extrn _isostate:isostate
340 mov bx,[_isostate.fd]
341 jmp lseekset ; (bx=fd, sz=cx:dx)
343 endp _isolseek
344 endif
347 ;***************************************************************
348 ;int strlen(const char* s);
349 ;***************************************************************
350 global _strlen:near
351 proc _strlen near
353 pop ax ;caller return address
354 pop bx ; s
355 push bx
356 push ax
357 global strlen:near ; strlen(bx)
358 strlen:
359 mov cx,bx
360 jcxz @@end
361 dec bx
362 @@lenlp:
363 inc bx
364 cmp [byte bx],0
365 jne @@lenlp
366 sub bx,cx
367 @@end:
368 xchg ax,bx
369 ret
371 endp _strlen
374 ;***************************************************************
375 ;int strhead(const char* a,const char* b);
376 ;***************************************************************
377 global _strhead:near
378 proc _strhead near
380 pop cx ;caller return address
381 pop bx ; a
382 pop ax ; b
383 push ax
384 push bx
385 push cx
386 @@loop:
387 xchg ax,bx
388 mov cl,[bx] ; cl = *b++
389 inc bx
390 or cl,cl ; clear C
391 jz fail ; return 0
392 xchg ax,bx
393 xor cl,[bx] ; cl -= *a++
394 inc bx
395 and cl,0dfh ; case insensitive
396 jz @@loop
397 ret ; return b (is not 0)
399 endp _strhead
402 ;***************************************************************
403 ;char* malloc_or_die(unsigned size);
404 ;***************************************************************
405 global _malloc_or_die:near
406 proc _malloc_or_die near
408 pop ax ;caller return address
409 pop cx ; size
410 push cx
411 push ax
412 global malloc_or_die:near ; malloc_or_die(cx)
413 malloc_or_die:
414 call malloc
415 jz _exit
416 ret
418 endp _malloc_or_die
421 ;***************************************************************
422 ;int die(const char* msg);
423 ;int exit();
424 ;int abort();
425 ;***************************************************************
426 global _die:near
427 proc _die near
429 pop ax ;caller return address
430 pop bx ; s
431 push bx
432 push ax
433 global die:near ; die(bx)
434 die:
435 call puts
436 global _exit:near
437 _exit:
438 mov al,[_no_exit]
439 cmp al,0
440 jne @@hang
441 extrn exit:near
442 inc ax
443 jmp near exit
444 @@hang:
445 mov bx, offset msg_hang
446 call puts
447 global _abort:near
448 _abort:
449 cli
450 @@stop:
451 hlt
452 jmp @@stop
454 endp _die
456 struc image_himem ;struct image_himem {
457 fd dw ? ; 0 int fd;
458 fallback dd ? ; 2 u32 fallback;
459 size dd ? ; 6 u32 size;
460 remaining dd ? ;10 u32 remaining;
461 buf dd ? ;14 u32 buf;
462 bufv dw ? ;18 u32 *bufv;
463 errmsg dw ? ;20 char *errmsg;
464 chunk_size dd ? ;22 u32 chunk_size;
465 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
466 state dw ? ;28 u16 state;
467 fd2close dw ? ;30 u16 fd2close;
468 ends ;};
470 ;***************************************************************
471 ;void next_chunk(struct image_himem *di);
472 ;***************************************************************
473 proc next_chunk near
475 push si
476 mov bx,[(image_himem di).fd]
477 call close
478 ifndef NO386
479 xor eax,eax
480 else
481 xor ax,ax
482 endif
483 cwd
484 mov [(image_himem di).fd],ax
485 mov bx,[(image_himem di).state]
486 cmp al,[bx] ; ""
487 jz @@end
488 mov si,bx
489 @@scan:
490 lodsb
491 mov cx,si
492 cmp al,','
493 jz @@eos
494 cmp al,0
495 jnz @@scan
496 dec cx
497 @@eos:
498 mov [(image_himem di).state],cx
499 dec si
500 push [word si]
501 mov [byte si],dl ; set temp eos
502 call open
503 pop [word si] ; restore string
504 jc @@die
505 mov [(image_himem di).fd],ax
506 mov [(image_himem di).fd2close],ax
507 xchg ax,bx
508 mov ax,4202h ; SEEK_END
509 call lseek0
510 @@die:
511 mov bx,[(image_himem di).errmsg]
512 jc die
513 mov bx,[(image_himem di).fd]
514 ifndef NO386
515 push eax
516 call rewind
517 pop eax
518 @@end:
519 mov [(image_himem di).chunk_size],eax
520 else
521 push ax
522 push dx
523 call rewind
524 pop dx
525 pop ax
526 @@end:
527 mov [word (image_himem di).chunk_size],ax
528 mov [word ((image_himem di).chunk_size)+2],dx
529 endif
530 pop si
531 ret
533 endp next_chunk
536 ifdef LARGE_IMAGES
537 struc data_himem ;struct data_himem {
538 first dd ? ; 0 u32 first;
539 cacheidx dw ? ; 4 int cacheidx;
540 pageidx dw ? ; 6 int pageidx;
541 cache dd 1024 dup(?) ; 8 int cache;
542 page dd 1024 dup(?) ;4104 int page;
543 ends ;}; // size=8200
544 endif
546 ;***************************************************************
547 ;u32* malloc_bufv_or_die(struct image_himem *m);
548 ;***************************************************************
549 global _malloc_bufv_or_die:near
550 proc _malloc_bufv_or_die near
552 p386
553 pop bx ;caller return address
554 pop ax
555 push ax
556 push bx
557 push si
558 xchg ax,si
559 ifdef LARGE_IMAGES
560 mov cx,[word ((image_himem si).size) + 2]
561 shr cx,4 ; pages index size = size >> 20
562 add cx,8+4096+8
563 call malloc_or_die
564 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
565 add ecx,[(image_himem si).size]
566 shr ecx,12
567 mov [curdata],ax
568 else
569 mov ecx,[(image_himem si).size]
570 dec ecx
571 shr ecx,12
572 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
573 push cx
574 inc cx ; cnt+1
575 shl cx,2 ; bufv => vcpi => vm86
576 ; our malloc zeroes allocated mem: bufv[cnt]=0;
577 ; Allocate pages, storing addrs in addrbuf
578 call malloc_or_die
579 pop cx
580 push ax
581 endif
582 mov [(image_himem si).bufv],ax
583 xchg ax,si
584 @@vcpi_alloc:
585 xor edx,edx
586 mov ax,0DE04h
587 int 67h
588 or ah,ah
589 mov bx,offset vcpi_alloc_err
590 jnz die
591 ; for (i = cnt-1; i >= 0; i--)
592 ifdef LARGE_IMAGES
593 mov eax,ecx
594 dec eax
595 else
596 mov ax,cx
597 dec ax
598 cwde
599 endif
600 shl eax,12 ; i*_4k
601 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
602 extrn _pm
603 mov bx,offset _pm+2
604 push eax
605 add eax,[bx-2+2]
606 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
607 pop eax ; i*_4k
608 jbe @@pmok
609 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
610 jae @@vcpi_alloc
611 @@pmok:
612 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
613 extrn _initrd
614 mov bx,offset _initrd+2
615 add eax,[bx-2+2] ; +initrd.fallback
616 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
617 ja @@initrdok
618 mov eax,[bx-2+6] ; initrd.size
619 add eax,[bx-2+2] ; +initrd.fallback
620 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
621 @@jnc_vcpi_alloc:
622 ja @@vcpi_alloc
623 @@initrdok:
624 ifdef LARGE_IMAGES
625 cmp [(data_himem si).first],0
626 jne @@notfirst
627 mov [(data_himem si).first],edx
628 @@notfirst:
629 mov bx,[(data_himem si).cacheidx]
630 cmp bh,4
631 jae @@nextpage
632 shl bx,2
633 inc [(data_himem si).cacheidx]
634 mov [(data_himem bx+si).cache],edx
635 loopd @@vcpi_alloc
636 mov [(data_himem bx+si).cache],ecx ; last is 0
637 @@nextpage:
638 and [(data_himem si).cacheidx],0
639 mov bx,[(data_himem si).pageidx]
640 mov [(data_himem bx+si).page],edx
641 add [(data_himem si).pageidx],4
642 push cx
643 lea cx,[(data_himem si).cache]
644 ifdef NO386
645 push edx
646 pop dx
647 pop ax
648 endif
649 call storepage ; storepage(edx,cx)
650 pop cx
651 or ecx,ecx ; clear C
652 jnz @@jnc_vcpi_alloc
653 mov [dword (data_himem si).cacheidx],ecx
654 xchg ax,si
655 else
656 mov [si],edx
657 lodsd ; si=+4
658 loop @@vcpi_alloc
659 pop ax
660 endif
661 pop si
662 ret
663 ifdef NO386
664 p8086
665 endif
667 endp _malloc_bufv_or_die
670 ;***************************************************************
671 ; void memcpy_image(struct image_himem *m);
672 ;***************************************************************
673 global _memcpy_image:near
674 proc _memcpy_image near
676 pop ax ;caller return address
677 pop bx
678 push bx
679 push ax
680 ifndef NO386
681 mov edx,[(image_himem bx).fallback]
682 mov eax,[(image_himem bx).buf]
683 cmp eax,edx ; if (m->fallback != m->buf)
684 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
685 ifdef LARGE_IMAGES
686 mov ecx,[(image_himem bx).size]
687 memcpy_imagez:
688 push ecx
689 else
690 push [(image_himem bx).size]
691 endif
692 push eax
693 push 0
694 call_memcpy32:
695 push edx
696 else
697 mov ax,[word ((image_himem bx).fallback)]
698 mov dx,[word ((image_himem bx).fallback)+2]
699 mov cx,[word ((image_himem bx).buf)]
700 cmp ax,cx ; if (m->fallback != m->buf)
701 jnz @@do
702 cmp dx,[word ((image_himem bx).buf)+2]
703 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
704 @@do:
705 push [word ((image_himem bx).size)+2]
706 push [word ((image_himem bx).size)]
707 push [word ((image_himem bx).buf)+2]
708 push cx
709 xor cx,cx
710 push cx
711 call_memcpy32:
712 push dx
713 push ax
714 ifdef LARGE_IMAGES
715 jmp @@memcpy
716 memcpy_imagez:
717 p386
718 push ecx
719 push eax
720 push 0
721 push edx
722 ifdef NO386
723 p8086
724 endif
725 endif
726 endif
727 @@memcpy:
728 extrn _memcpy32:near
729 call near _memcpy32
730 add sp,14
731 @@skip:
732 ret
734 endp _memcpy_image
736 ;***************************************************************
737 ;void storepage(u32 *dst, u16 src);
738 ;***************************************************************
739 global _storepage:near
740 proc _storepage near
742 pop ax ;caller return address
743 pop bx
744 pop cx
745 push cx
746 push bx
747 push ax
748 ifndef NO386
749 mov edx,[bx]
750 else
751 mov ax,[bx]
752 mov dx,[bx+2]
753 endif
754 storepage:
755 ifndef NO386
756 push 0
757 push 4096
758 push 0
759 else
760 xor bx,bx
761 push bx
762 mov bh,4096/256
763 push bx
764 xor bx,bx
765 push bx
766 endif
767 push cx
768 push ds
769 jmp call_memcpy32
771 endp _storepage
774 ifdef LARGE_IMAGES
775 p386
776 ;***************************************************************
777 ;void reset_bufv(u32 *p);
778 ;***************************************************************
779 global _reset_bufv:near
780 proc _reset_bufv near
782 pop ax ;caller return address
783 pop bx
784 push bx
785 push ax
786 mov [curdata],bx
787 and [dword (data_himem bx).cacheidx],0
788 ret
790 endp _reset_bufv
792 ;***************************************************************
793 ;u32* prev_bufv();
794 ;u32* prev_bufv();
795 ;***************************************************************
796 global _prev_bufv:near
797 global _next_bufv:near
798 proc _prev_bufv near
800 stc
801 db 73h ; jnc
802 _next_bufv:
803 clc
804 sbb ax,ax
805 stc
806 rcl ax,1 ; -1/+1
807 xor ecx,ecx
808 push si
809 mov si,[curdata]
810 add ax,[(data_himem si).cacheidx]
811 test ax,0fc00h
812 jz @@gotpage
813 push ax ; FFFF / 0400
814 sar ax,8 ; FFFC / 0004
815 and al,0fch
816 add [(data_himem si).pageidx],ax
817 mov bx,[(data_himem si).pageidx]
818 lea bx,[(data_himem bx+si).page]
819 mov edx,ds
820 shl edx,4
821 lea cx,[(data_himem si).cache]
822 add edx,ecx
823 mov eax,[bx]
824 or eax,eax
825 jnz @@pageok
826 pop ax
827 xchg ax,bx
828 pop si
829 ret
830 @@pageok:
831 mov cx,4096
832 call memcpy_imagez ; get page
833 pop ax ; FFFF / 0400
834 cbw
835 shr ax,6 ; 03FF / 0000
836 @@gotpage:
837 mov [(data_himem si).cacheidx],ax
838 shl ax,2
839 xchg ax,bx
840 lea ax,[(data_himem bx+si).cache]
841 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
842 jnz @@notfirst2
843 xchg ax,si ; &first
844 @@notfirst2:
845 pop si
846 ret
847 ifdef NO386
848 p8086
849 endif
851 endp _prev_bufv
852 endif
855 ;***************************************************************
856 ;void open_image(const char *name, struct image_himem *m);
857 ;***************************************************************
858 global _open_image:near
859 proc _open_image near
861 arg fname :word, \
862 m :word = PARAM_SIZE
864 push bp
865 mov bp,sp
866 push si di
867 ifndef NO386
868 xor eax,eax ; 1st loop flag + eos
869 else
870 xor ax,ax ; 1st loop flag + eos
871 endif
872 mov di,[m]
873 cmp [(image_himem di).fd],ax
874 jnz @@alreadydone
875 ifndef NO386
876 mov [(image_himem di).size],eax ; m->size = 0L
877 else
878 mov [word (image_himem di).size],ax ; m->size = 0L
879 mov [word ((image_himem di).size)+2],ax
880 endif
881 mov [(image_himem di).next_chunk],offset next_chunk
882 mov si,[fname]
883 mov [(image_himem di).state],si
884 @@next:
885 push di
886 call [(image_himem di).next_chunk] ; m->next_chunk()
887 pop di
888 ifndef NO386
889 add eax,3
890 and al,0FCh
891 add [(image_himem di).size],eax ; m->size += m->chunk_size
892 or eax,eax
893 jnz @@next
894 else
895 mov cx,ax
896 or cx,dx
897 add ax,3
898 adc dx,0
899 and al,0FCh
900 add [word (image_himem di).size],ax ; m->size += m->chunk_size
901 adc [word ((image_himem di).size)+2],dx
902 inc cx ; jcxnz
903 loop @@next
904 endif
905 mov [(image_himem di).state],si
906 push di
907 call [(image_himem di).next_chunk] ; m->next_chunk()
908 pop di
909 @@alreadydone:
910 push ax
911 image_done:
912 pop ax
913 pop di si bp
914 ret
916 endp _open_image
919 ;***************************************************************
920 ;int read_image(struct image_himem *m, void* data, int sz);
921 ;***************************************************************
922 global _read_image:near
923 proc _read_image near
925 arg m :word, \
926 data :word, \
927 sz :word = PARAM_SIZE
929 push bp
930 mov bp,sp
931 push si di
932 ifndef NO386
933 push 0 ; return value
934 else
935 xor ax,ax
936 push ax
937 endif
938 mov di,[m]
939 @@loop:
940 ifndef NO386
941 xor ecx,ecx
942 mov cx,[word sz]
943 @@chksz:
944 mov eax,[(image_himem di).chunk_size]
945 cmp ecx,eax
946 jb @@szok
947 xchg eax,ecx
948 else
949 mov cx,[word sz]
950 @@chksz:
951 mov ax,[word (image_himem di).chunk_size]
952 cmp cx,ax
953 jb @@szok
954 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
955 jne @@szok
956 xchg ax,cx
957 endif
958 @@szok:
959 jcxz image_done
960 push cx
961 push [word data]
962 push [word di]
963 call _read
964 pop dx
965 pop bx
966 pop dx
967 jc image_done
968 add bx,ax
969 xor cx,cx
970 ifndef NO386
971 cwde ; ax < 8000h
972 sub [(image_himem di).chunk_size],eax
973 else
974 cwd ; ax < 8000h
975 sub [word (image_himem di).chunk_size],ax
976 sbb [word ((image_himem di).chunk_size)+2],dx
977 jnz @@fill
978 cmp [word (image_himem di).chunk_size],dx
979 endif
980 jnz @@fill
981 dec cx
982 @@fill:
983 test al,3
984 je @@filled
985 mov [bx],dl
986 inc bx
987 inc ax
988 jmp @@fill
989 @@filled:
990 ifndef NO386
991 sub [(image_himem di).remaining],eax
992 else
993 sub [word (image_himem di).remaining],ax
994 sbb [word ((image_himem di).remaining)+2],dx
995 endif
996 add [bp-4-2],ax
997 add [word data],ax
998 sub [word sz],ax
999 pushf
1000 and cx,[(image_himem di).next_chunk]
1001 jz @@same_chunk
1002 push di
1003 call cx ; m->next_chunk()
1004 pop di
1005 @@same_chunk:
1006 popf
1007 jnz @@loop
1008 jmp image_done
1010 endp _read_image
1013 ;***************************************************************
1014 ;unsigned long strtol(const char *s);
1015 ;***************************************************************
1016 global _strtol:near
1017 proc _strtol near
1019 ifndef NO386
1020 pop ax ;caller return address
1021 pop cx ; s
1022 push cx
1023 push ax
1024 xor ebx,ebx
1025 push si
1026 jcxz @@end
1027 mov si,cx
1028 xor ecx,ecx
1029 xor eax,eax
1030 lodsb
1031 mov dx,ax
1032 or al,20h
1033 cmp al,'n' ; vga=normal
1034 je @@vga
1035 dec cx
1036 cmp al,'e' ; vga=extended
1037 je @@vga
1038 dec cx
1039 cmp al,'a' ; vga=ask
1040 jne @@notvga
1041 @@vga:
1042 dec cx
1043 xchg ax,cx
1044 cwd
1045 jmp @@popsiret
1046 @@notvga:
1047 mov cx,10 ; radix
1048 xchg ax,dx
1049 cmp al,'+'
1050 je @@radixskip
1051 cmp al,'-'
1052 clc
1053 jne @@radixkeep
1054 stc
1055 @@radixskip:
1056 lodsb
1057 @@radixkeep:
1058 pushf
1059 cmp al,'0'
1060 jne @@radixok
1061 mov cl,8
1062 lodsb
1063 or al,20h
1064 cmp al,'x'
1065 jne @@radixok
1066 mov cl,16
1067 @@strtollp:
1068 lodsb
1069 @@radixok:
1070 or al,20h
1071 sub al,'0'
1072 jb @@endstrtol
1073 cmp al,9
1074 jbe @@digitok
1075 cmp al,'a'-'0'
1076 jb @@endstrtol
1077 sub al,'a'-'0'-10
1078 @@digitok:
1079 cmp al,cl
1080 jae @@endstrtol
1081 xchg eax,ebx
1082 mul ecx
1083 add eax,ebx
1084 xchg eax,ebx
1085 jmp @@strtollp
1086 @@endstrtol:
1087 mov cl,10
1088 cmp al,'k'-'a'+10
1089 je @@shift
1090 mov cl,20
1091 cmp al,'m'-'a'+10
1092 je @@shift
1093 mov cl,30
1094 cmp al,'g'-'a'+10
1095 jne @@noshift
1096 @@shift:
1097 shl ebx,cl
1098 @@noshift:
1099 popf
1100 jnc @@end
1101 neg ebx
1102 @@end:
1103 push ebx
1104 pop ax
1105 pop dx
1106 @@popsiret:
1107 pop si
1108 else
1109 pop ax ;caller return address
1110 pop cx ; s
1111 push cx
1112 push ax
1113 push si
1114 push di
1115 xor ax,ax
1116 cwd
1117 jcxz @@goend
1118 xchg ax,di
1119 mov si,cx
1120 lodsb
1121 mov bx,ax
1122 or al,20h
1123 mov cx,-1
1124 cmp al,'n' ; vga=normal
1125 je @@vga
1126 dec cx
1127 cmp al,'e' ; vga=extended
1128 je @@vga
1129 dec cx
1130 cmp al,'a' ; vga=ask
1131 jne @@notvga
1132 @@vga:
1133 xchg ax,cx
1134 @@goend:
1135 jmp @@popdisiret
1136 @@notvga:
1137 mov cx,10 ; radix
1138 xchg ax,bx
1139 cmp al,'+'
1140 je @@radixskip
1141 cmp al,'-'
1142 clc
1143 jne @@radixkeep
1144 stc
1145 @@radixskip:
1146 lodsb
1147 @@radixkeep:
1148 pushf
1149 cmp al,'0'
1150 jne @@radixok
1151 mov cl,8
1152 lodsb
1153 mov al,20h
1154 cmp al,'x'
1155 jne @@radixok
1156 mov cl,16
1157 @@strtollp:
1158 lodsb
1159 @@radixok:
1160 or al,20h
1161 sub al,'0'
1162 jb @@endstrtol
1163 cmp al,9
1164 jbe @@digitok
1165 cmp al,'a'-'0'
1166 jb @@endstrtol
1167 sub al,'a'-'0'-10
1168 @@digitok:
1169 cmp al,cl
1170 jae @@endstrtol
1172 push ax
1173 push si
1174 push dx
1175 xchg ax,di
1176 mul cx
1177 xchg ax,di
1178 xchg ax,dx
1179 xchg ax,si
1180 pop ax
1181 mul cx
1182 add ax,si
1183 pop si
1184 xchg ax,dx
1185 pop ax
1186 mov ah,0
1187 add di,ax
1188 adc dx,0
1190 jmp @@strtollp
1191 @@endstrtol:
1192 mov cl,10
1193 cmp al,'k'-'a'+10
1194 je @@shift
1195 mov cl,20
1196 cmp al,'m'-'a'+10
1197 je @@shift
1198 mov cl,30
1199 cmp al,'g'-'a'+10
1200 jne @@noshift
1201 @@shift:
1202 rcl di,1
1203 shl dx,1
1204 loop @@shift
1205 @@noshift:
1206 popf
1207 jnc @@end
1208 not dx
1209 neg di
1210 jne @@end
1211 inc dx
1212 @@end:
1213 xchg ax,di
1214 @@popdisiret:
1215 pop di
1216 pop si
1217 endif
1218 ret
1220 endp _strtol
1223 ifdef NO386
1224 ;***************************************************************
1225 ;u16 topseg();
1226 ;***************************************************************
1227 global _topseg:near
1228 proc _topseg near
1230 int 12h
1231 jnc @@max640k
1232 mov ax,640 ; 9000
1233 @@max640k:
1234 dec ax
1235 and al,0C0h
1236 mov cl,6
1237 shl ax,cl
1238 ret
1240 endp _topseg
1241 endif
1243 ifdef EXTRA
1244 p8086
1246 ;***************************************************************
1247 ;int strcmp(const char* a,const char* b);
1248 ;***************************************************************
1249 global _strcmp:near
1250 proc _strcmp near
1252 pop cx ;caller return address
1253 pop bx ; a
1254 pop ax ; b
1255 push ax
1256 push bx
1257 push cx
1258 push si
1259 xchg ax,si
1260 sub bx,si
1261 @@lp:
1262 mov al,[si]
1263 sub al,[bx+si]
1264 jnz @@out
1265 lodsb
1266 cmp al,0
1267 jne @@lp
1268 @@out:
1269 cbw
1270 pop si
1271 ret
1273 endp _strcmp
1276 ;***************************************************************
1277 ;char strstr(const char* a,const char* b);
1278 ;***************************************************************
1279 global _strstr:near
1280 proc _strstr near
1282 pop ax ;caller return address
1283 pop cx ; a
1284 pop dx ; b
1285 push dx
1286 push cx
1287 push ax
1288 push si
1289 @@loop:
1290 xor ax,ax
1291 mov si,cx
1292 cmp [si],al ; *a
1293 jz @@end ; return ax = NULL
1294 mov bx,dx
1295 sub bx,si
1296 @@match:
1297 or ah,[bx+si] ; *b
1298 jz @@found
1299 lodsb
1300 sub ah,al
1301 jz @@match
1302 inc cx
1303 jmp @@loop
1304 @@found:
1305 xchg ax,cx
1306 @@end:
1307 pop si
1308 ret
1310 endp _strstr
1313 ;***************************************************************
1314 ;char *progname(void)
1315 ;***************************************************************
1316 global _progname:near
1317 proc _progname near
1319 push si di es
1320 mov ah,30h
1321 int 21h
1322 xor di,di
1323 cmp al,3
1324 mov ax,di
1325 jb @@skip
1326 ;mov es,[cs:2Ch]
1327 mov es,[di+2Ch]
1328 mov cx,-1
1329 @@loop:
1330 repne
1331 scasb
1332 scasb
1333 jne @@loop
1334 inc di
1335 inc di
1336 mov si,di ; progname @es:di
1337 repne
1338 scasb
1339 mov cx,di
1340 sub cx,si ; progname len
1341 call malloc_or_die ; keep cx
1342 mov di,ax
1343 push ds
1344 push es
1345 pop ds
1346 pop es
1347 rep
1348 movsb
1349 push es
1350 pop ds
1351 @@skip:
1352 pop es di si
1353 ret
1355 endp _progname
1358 ;***************************************************************
1359 ;void chdirname(char *path)
1360 ;***************************************************************
1361 global _chdirname:near
1362 proc _chdirname near
1364 pop ax
1365 pop bx
1366 push bx
1367 push ax
1369 cmp [byte bx+1],3Ah
1370 jne @@nodisk
1371 mov dl,20h
1372 or dl,[bx]
1373 sub dl,61h
1374 mov ah,0Eh
1375 int 21h
1376 inc bx
1377 inc bx
1378 @@nodisk:
1379 xor cx,cx
1380 @@next:
1381 mov al,[bx]
1382 cmp al,5Ch
1383 jne @@tsteos
1384 mov dx,bx
1385 inc cx
1386 @@tsteos:
1387 inc bx
1388 or al,al
1389 jnz @@next
1390 jcxz @@end
1391 mov bx,dx
1392 push [word bx]
1393 mov [bx],al
1394 stc
1395 mov ax,713Bh ; chdir long filename
1396 int 21h
1397 mov ah,3Bh ; chdir
1398 jnc chdirdone
1399 int 21h
1400 chdirdone:
1401 pop [word bx]
1402 @@end:
1403 ret
1405 endp _chdirname
1408 ;***************************************************************
1409 ;char *ultoa(unsigned long n);
1410 ;***************************************************************
1411 global _ultoa:near
1412 proc _ultoa near
1414 pop ax
1415 pop cx
1416 pop dx
1417 push dx
1418 push cx
1419 push ax ; DX:CX = n
1420 push si
1421 mov si,10
1422 mov bx,offset ultoabuf+11
1423 @@loop:
1424 dec bx
1425 xchg ax,dx
1426 xor dx,dx
1427 div si ; DX:AX = 0000:hi(n)
1428 xchg ax,cx ; CX = hi(n)/10
1429 div si ; DX:AX = hi(n)%10:lo(n)
1430 xchg ax,cx ; CX = lo(n/10)
1431 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1432 add al,'0'
1433 mov [bx],al
1434 mov ax,cx
1435 or ax,dx
1436 jnz @@loop
1437 xchg ax,bx
1438 pop si
1439 ret
1441 endp _ultoa
1444 ;***************************************************************
1445 ;unsigned long kver2ul(char *kernel_version);
1446 ;***************************************************************
1447 global _kver2ul:near
1448 proc _kver2ul near
1450 pop bx
1451 pop ax
1452 push ax
1453 push bx
1454 push bp si di
1455 xchg ax,si
1456 xor di,di
1457 push di
1458 push di
1459 mov bp,sp
1460 inc di
1461 inc di
1462 mov cl,4
1463 @@number:
1464 xor ax,ax
1465 @@digit:
1466 shl al,cl
1467 shl ax,cl
1468 lodsb
1469 sub al,30h
1470 cmp al,9
1471 jbe @@digit
1472 mov [bp+di],ah
1473 dec di
1474 jns @@number
1475 pop ax
1476 pop dx
1477 pop di si bp
1478 kver2ulret:
1479 ret
1481 endp _kver2ul
1484 ;***************************************************************
1485 ;void try_default_args();
1486 ;***************************************************************
1487 global _try_default_args:near
1488 proc _try_default_args near
1490 mov bx,offset tazboot_cmd
1491 call open
1492 jc kver2ulret
1493 mov cx,4096
1494 mov di,[_heap_top]
1495 push cx
1496 extrn read_cmdline:near
1497 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1499 endp _try_default_args
1501 endif
1503 ends _TEXT
1505 end
1507 ;###### END OF FILE ############################################