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

linld: add -b switch
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Dec 24 19:16:59 2016 +0100 (2016-12-24)
parents e428345df29a
children 38eb1fe036b4
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %crefref
6 %noincl
7 %nomacs
8 p386
10 group DGROUP _TEXT,_DATA,_BSS
11 assume cs:DGROUP,ds:DGROUP
13 segment _DATA byte public use16 'DATA'
15 global _heap_top:word
16 extrn _bss_end
17 _heap_top dw _bss_end
18 msg_hang db "High mem corrupted - not exiting to DOS"
19 msg_crlf db 13,10,0
20 vcpi_alloc_err db "vcpi "
21 msg_malloc db "malloc failure",0
23 ends _DATA
25 segment _BSS byte public use16 'BSS'
27 global _no_exit:byte
28 _no_exit db ?
29 filecnt db ? ; in fact 0 minus file count...
30 nextfilename dw ?
31 ifdef LARGE_IMAGES
32 curdata dw ?
33 endif
35 ends _BSS
37 segment _TEXT byte public use16 'CODE'
39 ;***************************************************************
40 ;char* strcpy(const char* a, const char* b);
41 ;char* strcat(const char* a, const char* b);
42 ;***************************************************************
43 global _strcpy:near
44 proc _strcpy near
46 mov dl,0
47 db 0bbh ; mov bx,imm opcode
48 global _strcat:near
49 _strcat:
50 mov dl,1
51 cat:
52 pop ax ;caller return address
53 pop cx ; a
54 pop bx ; b
55 push bx
56 push cx
57 push ax
58 push si
59 mov si,cx
60 shr dl,1
61 jnc @@nocat
62 @@catlp:
63 lodsb
64 cmp al,0
65 jne @@catlp
66 dec si
67 shr dl,1
68 jnc @@nocat
69 cmp cx,si
70 jz @@nocat
71 mov [word si],20h
72 inc si
73 @@nocat:
74 sub bx,si
75 @@cpylp:
76 mov al,[bx+si]
77 mov [si],al
78 inc si
79 cmp al,0
80 jne @@cpylp
81 mov ax,cx
82 pop si
83 ret
85 endp _strcpy
88 ;***************************************************************
89 ;char* strcatb(const char* a, const char* b);
90 ;***************************************************************
91 global _strcatb:near
92 proc _strcatb near
94 mov dl,3
95 jmp cat
97 endp _strcatb
100 ;***************************************************************
101 ;void* malloc(unsigned sz);
102 ;***************************************************************
103 global _malloc:near
104 proc _malloc near
106 pop ax ;caller return address
107 pop cx ; sz
108 push cx
109 push ax
110 global malloc:near ; malloc(cx)
111 malloc: ; keep CX, use AX,BX
112 mov ax,[_heap_top]
113 mov bx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
114 add bx,sp
115 sub bx,ax ; can't overflow
116 cmp bx,cx
117 mov bx,offset msg_malloc
118 jb puts
119 add [_heap_top],cx ; _BEG has zero'd heap
120 ;mov bx,ax
121 @@zalloc:
122 ;mov [byte bx],0
123 ;inc bx ; ZF=0
124 ;loop @@zalloc
125 ret
127 endp _malloc
130 ;***************************************************************
131 ;void puts(const char* s):
132 ;void putsz(const char* s):
133 ;***************************************************************
134 global _puts:near
135 proc _puts near
137 pop ax ;caller return address
138 pop bx ; s
139 push bx
140 push ax
141 global puts:near ; puts(bx)
142 puts:
143 call putsz
144 mov bx,offset msg_crlf
145 jmp putsz
147 global _putsz:near
148 _putsz:
149 pop ax ;caller return address
150 pop bx ; s
151 push bx
152 push ax
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 73h ; jnc
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 clc
260 jcxz fail
261 jmp dos
263 endp _read
266 ;***************************************************************
267 ;long lseekset(int fd, long sz);
268 ;***************************************************************
269 global _lseekset:near
270 proc _lseekset near
272 pop ax ;caller return address
273 pop bx ; fd
274 pop dx ; sz lo
275 pop cx ; sz hi
276 push cx
277 push dx
278 push bx
279 push ax
280 global lseekset:near
281 lseekset:
282 clc
283 global rewind:near
284 rewind: ; rewind(bx,C=1)
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
295 ;***************************************************************
296 ;int strlen(const char* s);
297 ;***************************************************************
298 global _strlen:near
299 proc _strlen near
301 pop ax ;caller return address
302 pop bx ; s
303 push bx
304 push ax
305 global strlen:near ; strlen(bx)
306 strlen:
307 mov cx,bx
308 jcxz @@end
309 dec bx
310 @@lenlp:
311 inc bx
312 cmp [byte bx],0
313 jne @@lenlp
314 sub bx,cx
315 @@end:
316 xchg ax,bx
317 ret
319 endp _strlen
322 ;***************************************************************
323 ;int strhead(const char* a,const char* b);
324 ;***************************************************************
325 global _strhead:near
326 proc _strhead near
328 pop cx ;caller return address
329 pop ax ; a
330 pop bx ; b
331 push bx
332 push ax
333 push cx
334 @@loop:
335 mov cl,[bx] ; cl = *b++
336 inc bx
337 or cl,cl ; clear C
338 jz fail ; return 0
339 xchg ax,bx
340 xor cl,[bx] ; cl -= *a++
341 and cl,0dfh ; case insensitive
342 stc
343 jnz fail ; return -1
344 inc bx
345 xchg ax,bx
346 jmp @@loop
348 endp _strhead
351 ;***************************************************************
352 ;char* malloc_or_die(unsigned size);
353 ;***************************************************************
354 global _malloc_or_die:near
355 proc _malloc_or_die near
357 pop ax ;caller return address
358 pop cx ; size
359 push cx
360 push ax
361 global malloc_or_die:near ; malloc_or_die(cx)
362 malloc_or_die:
363 call malloc
364 jz _exit
365 ret
367 endp _malloc_or_die
370 ;***************************************************************
371 ;int die(const char* msg);
372 ;int exit();
373 ;int abort();
374 ;***************************************************************
375 global _die:near
376 proc _die near
378 pop ax ;caller return address
379 pop bx ; s
380 push bx
381 push ax
382 global die:near ; die(bx)
383 die:
384 call puts
385 global _exit:near
386 _exit:
387 mov al,[_no_exit]
388 cmp al,0
389 jne @@hang
390 extrn exit:near
391 inc ax
392 jmp near exit
393 @@hang:
394 mov bx, offset msg_hang
395 call puts
396 global _abort:near
397 _abort:
398 cli
399 @@stop:
400 hlt
401 jmp @@stop
403 endp _die
405 struc image_himem ;struct image_himem {
406 fd dw ? ; 0 int fd;
407 fallback dd ? ; 2 u32 fallback;
408 size dd ? ; 6 u32 size;
409 remaining dd ? ;10 u32 remaining;
410 buf dd ? ;14 u32 buf;
411 bufv dw ? ;18 u32 *bufv;
412 errmsg dw ? ;20 char *errmsg;
413 chunk_size dd ? ;22 u32 chunk_size;
414 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
415 state dw ? ;28 u16 state;
416 fd2close dw ? ;30 u16 fd2close;
417 ends ;};
419 ifdef LARGE_IMAGES
420 struc data_himem ;struct data_himem {
421 first dd ? ; 0 u32 first;
422 cacheidx dw ? ; 4 int cacheidx;
423 pageidx dw ? ; 6 int pageidx;
424 cache dd 1024 dup(?) ; 8 int cache;
425 page dd 1024 dup(?) ;4104 int page;
426 ends ;}; // size=8200
427 endif
429 ;***************************************************************
430 ;u32* malloc_bufv_or_die(struct image_himem *m);
431 ;***************************************************************
432 global _malloc_bufv_or_die:near
433 proc _malloc_bufv_or_die near
435 pop bx ;caller return address
436 pop ax
437 push ax
438 push bx
439 push si
440 xchg ax,si
441 ifdef LARGE_IMAGES
442 mov cx,[word ((image_himem si).size) + 2]
443 shr cx,4 ; pages index size = size >> 20
444 add cx,8+4096+8
445 call malloc_or_die
446 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
447 add ecx,[(image_himem si).size]
448 shr ecx,12
449 mov [curdata],ax
450 else
451 mov ecx,[(image_himem si).size]
452 dec ecx
453 shr ecx,12
454 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
455 push cx
456 inc cx ; cnt+1
457 shl cx,2 ; bufv => vcpi => vm86
458 ; our malloc zeroes allocated mem: bufv[cnt]=0;
459 ; Allocate pages, storing addrs in addrbuf
460 call malloc_or_die
461 pop cx
462 push ax
463 endif
464 mov [(image_himem si).bufv],ax
465 xchg ax,si
466 @@vcpi_alloc:
467 xor edx,edx
468 mov ax,0DE04h
469 int 67h
470 or ah,ah
471 mov bx,offset vcpi_alloc_err
472 jnz die
473 ; for (i = cnt-1; i >= 0; i--)
474 ifdef LARGE_IMAGES
475 mov eax,ecx
476 dec eax
477 else
478 mov ax,cx
479 dec ax
480 cwde
481 endif
482 shl eax,12 ; i*_4k
483 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
484 extrn _pm
485 mov bx,offset _pm+2
486 push eax
487 add eax,[bx-2+2]
488 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
489 pop eax ; i*_4k
490 jbe @@pmok
491 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
492 jae @@vcpi_alloc
493 @@pmok:
494 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
495 extrn _initrd
496 mov bx,offset _initrd+2
497 add eax,[bx-2+2] ; +initrd.fallback
498 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
499 ja @@initrdok
500 mov eax,[bx-2+6] ; initrd.size
501 add eax,[bx-2+2] ; +initrd.fallback
502 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
503 @@jnc_vcpi_alloc:
504 ja @@vcpi_alloc
505 @@initrdok:
506 ifdef LARGE_IMAGES
507 cmp [(data_himem si).first],0
508 jne @@notfirst
509 mov [(data_himem si).first],edx
510 @@notfirst:
511 mov bx,[(data_himem si).cacheidx]
512 cmp bh,4
513 jae @@nextpage
514 shl bx,2
515 inc [(data_himem si).cacheidx]
516 mov [(data_himem bx+si).cache],edx
517 loopd @@vcpi_alloc
518 mov [(data_himem bx+si).cache],ecx ; last is 0
519 @@nextpage:
520 and [(data_himem si).cacheidx],0
521 mov bx,[(data_himem si).pageidx]
522 mov [(data_himem bx+si).page],edx
523 add [(data_himem si).pageidx],4
524 push cx
525 lea cx,[(data_himem si).cache]
526 ifdef NO386
527 push edx
528 pop dx
529 pop ax
530 endif
531 call storepage ; storepage(edx,cx)
532 pop cx
533 or ecx,ecx ; clear C
534 jnz @@jnc_vcpi_alloc
535 mov [dword (data_himem si).cacheidx],ecx
536 xchg ax,si
537 else
538 mov [si],edx
539 lodsd ; si=+4
540 loop @@vcpi_alloc
541 pop ax
542 endif
543 pop si
544 ret
546 endp _malloc_bufv_or_die
549 ;***************************************************************
550 ; void memcpy_image(struct image_himem *m);
551 ;***************************************************************
552 global _memcpy_image:near
553 proc _memcpy_image near
555 pop ax ;caller return address
556 pop bx
557 push bx
558 push ax
559 ifndef NO386
560 mov edx,[(image_himem bx).fallback]
561 mov eax,[(image_himem bx).buf]
562 cmp eax,edx ; if (m->fallback != m->buf)
563 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
564 ifdef LARGE_IMAGES
565 mov ecx,[(image_himem bx).size]
566 memcpy_imagez:
567 push ecx
568 else
569 push [(image_himem bx).size]
570 endif
571 push eax
572 push 0
573 call_memcpy32:
574 push edx
575 else
576 mov ax,[word ((image_himem bx).fallback)]
577 mov dx,[word ((image_himem bx).fallback)+2]
578 mov cx,[word ((image_himem bx).buf)]
579 cmp ax,cx ; if (m->fallback != m->buf)
580 jnz @@do
581 cmp dx,[word ((image_himem bx).buf)+2]
582 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
583 @@do:
584 push [word ((image_himem bx).size)+2]
585 push [word ((image_himem bx).size)]
586 push [word ((image_himem bx).buf)+2]
587 push cx
588 xor cx,cx
589 push cx
590 call_memcpy32:
591 push dx
592 push ax
593 ifdef LARGE_IMAGES
594 jmp @@memcpy
595 memcpy_imagez:
596 push ecx
597 push eax
598 push 0
599 push edx
600 endif
601 endif
602 @@memcpy:
603 extrn _memcpy32:near
604 call near _memcpy32
605 add sp,14
606 @@skip:
607 ret
609 endp _memcpy_image
611 ;***************************************************************
612 ;void storepage(u32 *dst, u16 src);
613 ;***************************************************************
614 global _storepage:near
615 proc _storepage near
617 pop ax ;caller return address
618 pop bx
619 pop cx
620 push cx
621 push bx
622 push ax
623 ifndef NO386
624 mov edx,[bx]
625 else
626 mov ax,[bx]
627 mov dx,[bx+2]
628 endif
629 storepage:
630 ifndef NO386
631 push 0
632 push 4096
633 push 0
634 else
635 xor bx,bx
636 push bx
637 mov bh,4096/256
638 push bx
639 xor bx,bx
640 push bx
641 endif
642 push cx
643 push ds
644 jmp call_memcpy32
646 endp _storepage
649 ifdef LARGE_IMAGES
650 ;***************************************************************
651 ;void reset_bufv(u32 *p);
652 ;***************************************************************
653 global _reset_bufv:near
654 proc _reset_bufv near
656 pop bx ;caller return address
657 pop ax
658 push ax
659 push bx
660 mov [curdata],ax
661 xchg ax,bx
662 and [dword (data_himem bx).cacheidx],0
663 ret
665 endp _reset_bufv
667 ;***************************************************************
668 ;u32* prev_bufv();
669 ;u32* prev_bufv();
670 ;***************************************************************
671 global _prev_bufv:near
672 global _next_bufv:near
673 proc _prev_bufv near
675 stc
676 db 73h ; jnc
677 _next_bufv:
678 clc
679 sbb ax,ax
680 stc
681 rcl ax,1 ; -1/+1
682 xor ecx,ecx
683 push si
684 mov si,[curdata]
685 add ax,[(data_himem si).cacheidx]
686 test ax,0fc00h
687 jz @@gotpage
688 push ax ; FFFF / 0400
689 sar ax,8 ; FFFC / 0004
690 and al,0fch
691 add [(data_himem si).pageidx],ax
692 mov bx,[(data_himem si).pageidx]
693 lea bx,[(data_himem bx+si).page]
694 mov edx,ds
695 shl edx,4
696 lea cx,[(data_himem si).cache]
697 add edx,ecx
698 mov eax,[bx]
699 or eax,eax
700 jnz @@pageok
701 pop ax
702 xchg ax,bx
703 pop si
704 ret
705 @@pageok:
706 mov cx,4096
707 call memcpy_imagez ; get page
708 pop ax ; FFFF / 0400
709 cbw
710 shr ax,6 ; 03FF / 0000
711 @@gotpage:
712 mov [(data_himem si).cacheidx],ax
713 shl ax,2
714 xchg ax,bx
715 lea ax,[(data_himem bx+si).cache]
716 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
717 jnz @@notfirst2
718 xchg ax,si ; &first
719 @@notfirst2:
720 pop si
721 ret
723 endp _prev_bufv
724 endif
727 ;***************************************************************
728 ;void next_chunk(struct image_himem *m);
729 ;***************************************************************
730 proc next_chunk near
732 push si
733 mov bx,[(image_himem di).fd]
734 call close
735 ifndef NO386
736 xor eax,eax
737 else
738 xor ax,ax
739 endif
740 cwd
741 mov [(image_himem di).fd],ax
742 mov bx,[(image_himem di).state]
743 cmp al,[bx] ; ""
744 jz @@end
745 mov si,bx
746 @@scan:
747 lodsb
748 mov cx,si
749 cmp al,','
750 jz @@eos
751 cmp al,0
752 jnz @@scan
753 dec cx
754 @@eos:
755 mov [(image_himem di).state],cx
756 dec si
757 push [word si]
758 mov [byte si],dl ; set temp eos
759 call open
760 pop [word si] ; restore string
761 jc @@die
762 mov [(image_himem di).fd],ax
763 mov [(image_himem di).fd2close],ax
764 xchg ax,bx
765 mov ax,4202h ; SEEK_END
766 call lseek0
767 @@die:
768 mov bx,[(image_himem di).errmsg]
769 jc die
770 mov bx,[(image_himem di).fd]
771 ifndef NO386
772 push eax
773 stc
774 call rewind
775 pop eax
776 @@end:
777 mov [(image_himem di).chunk_size],eax
778 else
779 push ax
780 push dx
781 stc
782 call rewind
783 pop dx
784 pop ax
785 @@end:
786 mov [word (image_himem di).chunk_size],ax
787 mov [word ((image_himem di).chunk_size)+2],dx
788 endif
789 pop si
790 ret
792 endp next_chunk
795 ;***************************************************************
796 ;void open_image(const char *name, struct image_himem *m);
797 ;***************************************************************
798 global _open_image:near
799 proc _open_image near
801 arg fname :word, \
802 m :word = PARAM_SIZE
804 push bp
805 mov bp,sp
806 push si di
807 ifndef NO386
808 xor eax,eax ; 1st loop flag + eos
809 else
810 xor ax,ax ; 1st loop flag + eos
811 endif
812 mov di,[m]
813 cmp [(image_himem di).fd],ax
814 jnz @@alreadydone
815 ifndef NO386
816 mov [(image_himem di).size],eax ; m->size = 0L
817 else
818 mov [word (image_himem di).size],ax ; m->size = 0L
819 mov [word ((image_himem di).size)+2],ax
820 endif
821 mov [(image_himem di).next_chunk],offset next_chunk
822 mov si,[fname]
823 mov [(image_himem di).state],si
824 @@next:
825 push di
826 call [(image_himem di).next_chunk] ; m->next_chunk()
827 pop di
828 ifndef NO386
829 add eax,3
830 and al,0FCh
831 add [(image_himem di).size],eax ; m->size += m->chunk_size
832 or eax,eax
833 jnz @@next
834 else
835 mov cx,ax
836 or cx,dx
837 add ax,3
838 adc dx,0
839 and al,0FCh
840 add [word (image_himem di).size],ax ; m->size += m->chunk_size
841 adc [word ((image_himem di).size)+2],dx
842 inc cx ; jcxnz
843 loop @@next
844 endif
845 mov [(image_himem di).state],si
846 push di
847 call [(image_himem di).next_chunk] ; m->next_chunk()
848 pop di
849 @@alreadydone:
850 push ax
851 image_done:
852 pop ax
853 pop di si bp
854 ret
856 endp _open_image
859 ;***************************************************************
860 ;int read_image(struct image_himem *m, void* data, int sz);
861 ;***************************************************************
862 global _read_image:near
863 proc _read_image near
865 arg m :word, \
866 data :word, \
867 sz :word = PARAM_SIZE
869 push bp
870 mov bp,sp
871 push si di
872 ifndef NO386
873 push 0 ; return value
874 else
875 xor ax,ax
876 push ax
877 endif
878 mov di,[m]
879 @@loop:
880 ifndef NO386
881 xor ecx,ecx
882 mov cx,[word sz]
883 @@chksz:
884 mov eax,[(image_himem di).chunk_size]
885 cmp ecx,eax
886 jb @@szok
887 xchg eax,ecx
888 else
889 mov cx,[word sz]
890 @@chksz:
891 mov ax,[word (image_himem di).chunk_size]
892 cmp cx,ax
893 jb @@szok
894 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
895 jne @@szok
896 xchg ax,cx
897 endif
898 @@szok:
899 jcxz image_done
900 push cx
901 push [word data]
902 push [word di]
903 call _read
904 pop dx
905 pop bx
906 pop dx
907 jc image_done
908 add bx,ax
909 xor cx,cx
910 ifndef NO386
911 cwde ; ax < 8000h
912 cwd
913 sub [(image_himem di).chunk_size],eax
914 else
915 cwd ; ax < 8000h
916 sub [word (image_himem di).chunk_size],ax
917 sbb [word ((image_himem di).chunk_size)+2],dx
918 jnz @@fill
919 cmp [word (image_himem di).chunk_size],dx
920 endif
921 jnz @@fill
922 dec cx
923 @@fill:
924 test al,3
925 je @@filled
926 mov [bx],dl
927 inc bx
928 inc ax
929 jmp @@fill
930 @@filled:
931 ifndef NO386
932 sub [(image_himem di).remaining],eax
933 else
934 sub [word (image_himem di).remaining],ax
935 sbb [word ((image_himem di).remaining)+2],dx
936 endif
937 add [bp-4-2],ax
938 add [word data],ax
939 sub [word sz],ax
940 pushf
941 and cx,[(image_himem di).next_chunk]
942 jz @@same_chunk
943 push di
944 call cx ; m->next_chunk()
945 pop di
946 @@same_chunk:
947 popf
948 jnz @@loop
949 jmp image_done
951 endp _read_image
954 ;***************************************************************
955 ;unsigned long strtol(const char *s);
956 ;***************************************************************
957 global _strtol:near
958 proc _strtol near
960 ifndef NO386
961 pop ax ;caller return address
962 pop cx ; s
963 push cx
964 push ax
965 xor ebx,ebx
966 jcxz @@jncend
967 push si
968 mov si,cx
969 xor ecx,ecx
970 xor eax,eax
971 lodsb
972 mov dl,20h
973 or dl,al
974 cmp dl,'n' ; vga=normal
975 je @@vga
976 dec cx
977 cmp dl,'e' ; vga=extended
978 je @@vga
979 dec cx
980 cmp dl,'a' ; vga=ask
981 jne @@notvga
982 @@vga:
983 dec cx
984 xchg ax,cx
985 cwd
986 jmp popsiret
987 @@notvga:
988 mov cx,10 ; radix
989 cmp al,'+'
990 je @@radixskip
991 cmp al,'-'
992 clc
993 jne @@radixkeep
994 stc
995 @@radixskip:
996 lodsb
997 @@radixkeep:
998 pushf
999 cmp al,'0'
1000 jne @@radixok
1001 mov cl,8
1002 lodsb
1003 mov dl,20h
1004 or dl,al
1005 cmp dl,'x'
1006 jne @@radixok
1007 mov cl,16
1008 @@strtollp:
1009 lodsb
1010 @@radixok:
1011 sub al,'0'
1012 jb @@endstrtol
1013 cmp al,9
1014 jbe @@digitok
1015 or al,20h
1016 cmp al,'a'-'0'
1017 jb @@endstrtol
1018 sub al,'a'-'0'-10
1019 @@digitok:
1020 cmp al,cl
1021 jae @@endstrtol
1022 xchg eax,ebx
1023 mul ecx
1024 add eax,ebx
1025 xchg eax,ebx
1026 jmp @@strtollp
1027 @@endstrtol:
1028 mov cl,10
1029 cmp al,'k'-'a'+10
1030 je @@shift
1031 mov cl,20
1032 cmp al,'m'-'a'+10
1033 je @@shift
1034 mov cl,30
1035 cmp al,'g'-'a'+10
1036 jne @@noshift
1037 @@shift:
1038 shl ebx,cl
1039 @@noshift:
1040 popf
1041 @@jncend:
1042 jnc @@end
1043 neg ebx
1044 @@end:
1045 push ebx
1046 pop ax
1047 pop dx
1048 popsiret:
1049 pop si
1050 else
1051 pop ax ;caller return address
1052 pop cx ; s
1053 push cx
1054 push ax
1055 push si
1056 push di
1057 xor ax,ax
1058 cwd
1059 xchg ax,di
1060 jcxz @@goend
1061 mov si,cx
1062 lodsb
1063 mov dl,20h
1064 or dl,al
1065 mov cx,-1
1066 cmp dl,'n' ; vga=normal
1067 je @@vga
1068 dec cx
1069 cmp dl,'e' ; vga=extended
1070 je @@vga
1071 dec cx
1072 cmp dl,'a' ; vga=ask
1073 jne @@notvga
1074 @@vga:
1075 xchg ax,cx
1076 cwd
1077 jmp popsiret
1078 @@goend:
1079 jmp @@end
1080 @@notvga:
1081 mov cx,10 ; radix
1082 cmp al,'+'
1083 je @@radixskip
1084 cmp al,'-'
1085 clc
1086 jne @@radixkeep
1087 stc
1088 @@radixskip:
1089 lodsb
1090 @@radixkeep:
1091 pushf
1092 cmp al,'0'
1093 jne @@radixok
1094 mov cl,8
1095 lodsb
1096 mov ah,20h
1097 or ah,al
1098 cmp ah,'x'
1099 jne @@radixok
1100 mov cl,16
1101 @@strtollp:
1102 lodsb
1103 @@radixok:
1104 sub al,'0'
1105 jb @@endstrtol
1106 cmp al,9
1107 jbe @@digitok
1108 or al,20h
1109 cmp al,'a'-'0'
1110 jb @@endstrtol
1111 sub al,'a'-'0'-10
1112 @@digitok:
1113 cmp al,cl
1114 jae @@endstrtol
1116 push ax
1117 push si
1118 push dx
1119 xchg ax,di
1120 mul cx
1121 xchg ax,di
1122 xchg ax,dx
1123 xchg ax,si
1124 pop ax
1125 mul cx
1126 add ax,si
1127 pop si
1128 xchg ax,dx
1129 pop ax
1130 mov ah,0
1131 add di,ax
1132 adc dx,0
1134 jmp @@strtollp
1135 @@endstrtol:
1136 mov cl,10
1137 cmp al,'k'-'a'+10
1138 je @@shift
1139 mov cl,20
1140 cmp al,'m'-'a'+10
1141 je @@shift
1142 mov cl,30
1143 cmp al,'g'-'a'+10
1144 jne @@noshift
1145 @@shift:
1146 rcl di,1
1147 shl dx,1
1148 loop @@shift
1149 @@noshift:
1150 popf
1151 jnc @@end
1152 not dx
1153 neg di
1154 jne @@end
1155 inc dx
1156 @@end:
1157 xchg ax,di
1158 pop di
1159 popsiret:
1160 pop si
1161 endif
1162 ret
1164 endp _strtol
1167 ifdef NO386
1168 ;***************************************************************
1169 ;u16 topseg();
1170 ;***************************************************************
1171 global _topseg:near
1172 proc _topseg near
1174 int 12h
1175 jnc @@max640k
1176 mov ax,640 ; 9000
1177 @@max640k:
1178 sub ax,028h
1179 and al,0C0h
1180 mov cl,6
1181 shl ax,cl
1182 ret
1184 endp _topseg
1185 endif
1187 ends _TEXT
1189 end
1191 ;###### END OF FILE ############################################