wok-6.x view linld/stuff/src/CRTL.ASM @ rev 19634

linld: some fixes for strtoul
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Jan 16 10:15:15 2017 +0100 (2017-01-16)
parents 23fc786c04e8
children 76087975885f
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 ;char* strcatb(const char* a, const char* b);
43 ;***************************************************************
44 global _strcpy:near
45 proc _strcpy near
47 mov dl,0
48 db 0bbh ; mov bx,imm opcode
49 global _strcat:near
50 _strcat:
51 mov dl,1
52 db 0bbh ; mov bx,imm opcode
53 global _strcatb:near
54 _strcatb:
55 mov dl,3
56 pop ax ;caller return address
57 pop cx ; a
58 pop bx ; b
59 push bx
60 push cx
61 push ax
62 push si
63 mov si,cx
64 shr dl,1
65 jnc @@nocat
66 @@catlp:
67 lodsb
68 cmp al,0
69 jne @@catlp
70 dec si
71 shr dl,1
72 jnc @@nocat
73 cmp cx,si
74 jz @@nocat
75 mov [word si],20h
76 inc si
77 @@nocat:
78 sub bx,si
79 @@cpylp:
80 mov al,[bx+si]
81 mov [si],al
82 inc si
83 cmp al,0
84 jne @@cpylp
85 mov ax,cx
86 pop si
87 ret
89 endp _strcpy
92 ;***************************************************************
93 ;void* malloc(unsigned sz);
94 ;***************************************************************
95 global _malloc:near
96 proc _malloc near
98 pop ax ;caller return address
99 pop cx ; sz
100 push cx
101 push ax
102 global malloc:near ; malloc(cx)
103 malloc: ; keep CX, use AX,BX
104 mov ax,[_heap_top]
105 mov bx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
106 add bx,sp
107 sub bx,ax ; can't overflow
108 cmp bx,cx
109 mov bx,offset msg_malloc
110 jb puts
111 add [_heap_top],cx ; _BEG has zero'd heap
112 ;mov bx,ax
113 @@zalloc:
114 ;mov [byte bx],0
115 ;inc bx ; ZF=0
116 ;loop @@zalloc
117 ret
119 endp _malloc
122 ;***************************************************************
123 ;void puts(const char* s):
124 ;***************************************************************
125 global _puts:near
126 proc _puts near
128 pop ax ;caller return address
129 pop bx ; s
130 push bx
131 push ax
132 global puts:near ; puts(bx)
133 puts:
134 call putsz
135 mov bx,offset msg_crlf
137 global putsz:near ; putsz(bx)
138 putsz:
139 push bx
140 call strlen
141 pop dx
142 xchg ax,cx
143 mov bx,1
144 mov ah,40h
145 int 21h
146 xor ax,ax ; ZF=1 (for malloc failure)
147 ret
149 endp _puts
152 ;***************************************************************
153 ;int fileattr(const char* name);
154 ;***************************************************************
155 global _fileattr:near
156 proc _fileattr near
158 pop ax ;caller return address
159 pop dx ; name
160 push dx
161 push ax
162 mov ax,4300h
163 int 21h
164 xchg ax,cx
165 jmp chkc
167 endp _fileattr
170 ;***************************************************************
171 ;int open(const char* name, int flags=O_RDONLY);
172 ;***************************************************************
173 global _open:near
174 proc _open near
176 pop ax ;caller return address
177 pop bx ; name
178 push bx
179 push ax
180 global open:near ; open(bx)
181 open:
182 mov dx,bx
183 mov ax,3d00h
184 dos:
185 int 21h
186 chkc:
187 jnc doret
188 fail:
189 sbb ax,ax ; ax=-1 CF
190 cwd
191 doret:
192 ifndef NO386
193 push dx ; see next_chunk:lseek
194 push ax
195 pop eax
196 endif
197 ret
199 endp _open
202 ;***************************************************************
203 ;int close(int fd);
204 ;***************************************************************
205 global _close:near
206 proc _close near
208 pop ax ;caller return address
209 pop bx ; fd
210 push bx
211 push ax
212 global close:near ; close(bx)
213 close:
214 mov ah,3Eh
215 or bx,bx
216 jnz dos
217 ret
219 endp _close
222 ;***************************************************************
223 ;int read(int fd, void* data, int sz);
224 ;int write(int fd, const void* data, int sz);
225 ;***************************************************************
226 global _read:near
227 proc _read near
229 stc
230 db 0B0h ; mov al,im
231 global _write:near
232 clc
233 pop ax ;caller return address
234 pop bx ; fd
235 pop dx ; data
236 pop cx ; sz
237 push cx
238 push dx
239 push bx
240 push ax
241 mov ah,40h
242 sbb ah,0
243 jcxz fail
244 jmp dos
246 endp _read
249 ;***************************************************************
250 ;long lseekset(int fd, long sz);
251 ;***************************************************************
252 global _lseekset:near
253 proc _lseekset near
255 pop ax ;caller return address
256 pop bx ; fd
257 pop dx ; sz lo
258 pop cx ; sz hi
259 push cx
260 push dx
261 push bx
262 push ax
263 global lseekset:near
264 lseekset:
265 clc
266 db 0B0h ; mov al,im
267 global rewind:near
268 rewind: ; rewind(bx)
269 stc
270 mov ax,4200h
271 jnc dos
272 lseek0: ; lseek0(bx,ax=dir)
273 cwd
274 xor cx,cx
275 jmp dos
277 endp _lseekset
280 ;***************************************************************
281 ;int strlen(const char* s);
282 ;***************************************************************
283 global _strlen:near
284 proc _strlen near
286 pop ax ;caller return address
287 pop bx ; s
288 push bx
289 push ax
290 global strlen:near ; strlen(bx)
291 strlen:
292 mov cx,bx
293 jcxz @@end
294 dec bx
295 @@lenlp:
296 inc bx
297 cmp [byte bx],0
298 jne @@lenlp
299 sub bx,cx
300 @@end:
301 xchg ax,bx
302 ret
304 endp _strlen
307 ;***************************************************************
308 ;int strhead(const char* a,const char* b);
309 ;***************************************************************
310 global _strhead:near
311 proc _strhead near
313 pop cx ;caller return address
314 pop bx ; a
315 pop ax ; b
316 push ax
317 push bx
318 push cx
319 @@loop:
320 xchg ax,bx
321 mov cl,[bx] ; cl = *b++
322 inc bx
323 or cl,cl ; clear C
324 jz fail ; return 0
325 xchg ax,bx
326 xor cl,[bx] ; cl -= *a++
327 inc bx
328 and cl,0dfh ; case insensitive
329 jz @@loop
330 ret ; return b (is not 0)
332 endp _strhead
335 ;***************************************************************
336 ;char* malloc_or_die(unsigned size);
337 ;***************************************************************
338 global _malloc_or_die:near
339 proc _malloc_or_die near
341 pop ax ;caller return address
342 pop cx ; size
343 push cx
344 push ax
345 global malloc_or_die:near ; malloc_or_die(cx)
346 malloc_or_die:
347 call malloc
348 jz _exit
349 ret
351 endp _malloc_or_die
354 ;***************************************************************
355 ;int die(const char* msg);
356 ;int exit();
357 ;int abort();
358 ;***************************************************************
359 global _die:near
360 proc _die near
362 pop ax ;caller return address
363 pop bx ; s
364 push bx
365 push ax
366 global die:near ; die(bx)
367 die:
368 call puts
369 global _exit:near
370 _exit:
371 mov al,[_no_exit]
372 cmp al,0
373 jne @@hang
374 extrn exit:near
375 inc ax
376 jmp near exit
377 @@hang:
378 mov bx, offset msg_hang
379 call puts
380 global _abort:near
381 _abort:
382 cli
383 @@stop:
384 hlt
385 jmp @@stop
387 endp _die
389 struc image_himem ;struct image_himem {
390 fd dw ? ; 0 int fd;
391 fallback dd ? ; 2 u32 fallback;
392 size dd ? ; 6 u32 size;
393 remaining dd ? ;10 u32 remaining;
394 buf dd ? ;14 u32 buf;
395 bufv dw ? ;18 u32 *bufv;
396 errmsg dw ? ;20 char *errmsg;
397 chunk_size dd ? ;22 u32 chunk_size;
398 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
399 state dw ? ;28 u16 state;
400 fd2close dw ? ;30 u16 fd2close;
401 ends ;};
403 ifdef LARGE_IMAGES
404 struc data_himem ;struct data_himem {
405 first dd ? ; 0 u32 first;
406 cacheidx dw ? ; 4 int cacheidx;
407 pageidx dw ? ; 6 int pageidx;
408 cache dd 1024 dup(?) ; 8 int cache;
409 page dd 1024 dup(?) ;4104 int page;
410 ends ;}; // size=8200
411 endif
413 ;***************************************************************
414 ;u32* malloc_bufv_or_die(struct image_himem *m);
415 ;***************************************************************
416 global _malloc_bufv_or_die:near
417 proc _malloc_bufv_or_die near
419 pop bx ;caller return address
420 pop ax
421 push ax
422 push bx
423 push si
424 xchg ax,si
425 ifdef LARGE_IMAGES
426 mov cx,[word ((image_himem si).size) + 2]
427 shr cx,4 ; pages index size = size >> 20
428 add cx,8+4096+8
429 call malloc_or_die
430 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
431 add ecx,[(image_himem si).size]
432 shr ecx,12
433 mov [curdata],ax
434 else
435 mov ecx,[(image_himem si).size]
436 dec ecx
437 shr ecx,12
438 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
439 push cx
440 inc cx ; cnt+1
441 shl cx,2 ; bufv => vcpi => vm86
442 ; our malloc zeroes allocated mem: bufv[cnt]=0;
443 ; Allocate pages, storing addrs in addrbuf
444 call malloc_or_die
445 pop cx
446 push ax
447 endif
448 mov [(image_himem si).bufv],ax
449 xchg ax,si
450 @@vcpi_alloc:
451 xor edx,edx
452 mov ax,0DE04h
453 int 67h
454 or ah,ah
455 mov bx,offset vcpi_alloc_err
456 jnz die
457 ; for (i = cnt-1; i >= 0; i--)
458 ifdef LARGE_IMAGES
459 mov eax,ecx
460 dec eax
461 else
462 mov ax,cx
463 dec ax
464 cwde
465 endif
466 shl eax,12 ; i*_4k
467 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
468 extrn _pm
469 mov bx,offset _pm+2
470 push eax
471 add eax,[bx-2+2]
472 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
473 pop eax ; i*_4k
474 jbe @@pmok
475 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
476 jae @@vcpi_alloc
477 @@pmok:
478 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
479 extrn _initrd
480 mov bx,offset _initrd+2
481 add eax,[bx-2+2] ; +initrd.fallback
482 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
483 ja @@initrdok
484 mov eax,[bx-2+6] ; initrd.size
485 add eax,[bx-2+2] ; +initrd.fallback
486 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
487 @@jnc_vcpi_alloc:
488 ja @@vcpi_alloc
489 @@initrdok:
490 ifdef LARGE_IMAGES
491 cmp [(data_himem si).first],0
492 jne @@notfirst
493 mov [(data_himem si).first],edx
494 @@notfirst:
495 mov bx,[(data_himem si).cacheidx]
496 cmp bh,4
497 jae @@nextpage
498 shl bx,2
499 inc [(data_himem si).cacheidx]
500 mov [(data_himem bx+si).cache],edx
501 loopd @@vcpi_alloc
502 mov [(data_himem bx+si).cache],ecx ; last is 0
503 @@nextpage:
504 and [(data_himem si).cacheidx],0
505 mov bx,[(data_himem si).pageidx]
506 mov [(data_himem bx+si).page],edx
507 add [(data_himem si).pageidx],4
508 push cx
509 lea cx,[(data_himem si).cache]
510 ifdef NO386
511 push edx
512 pop dx
513 pop ax
514 endif
515 call storepage ; storepage(edx,cx)
516 pop cx
517 or ecx,ecx ; clear C
518 jnz @@jnc_vcpi_alloc
519 mov [dword (data_himem si).cacheidx],ecx
520 xchg ax,si
521 else
522 mov [si],edx
523 lodsd ; si=+4
524 loop @@vcpi_alloc
525 pop ax
526 endif
527 pop si
528 ret
530 endp _malloc_bufv_or_die
533 ;***************************************************************
534 ; void memcpy_image(struct image_himem *m);
535 ;***************************************************************
536 global _memcpy_image:near
537 proc _memcpy_image near
539 pop ax ;caller return address
540 pop bx
541 push bx
542 push ax
543 ifndef NO386
544 mov edx,[(image_himem bx).fallback]
545 mov eax,[(image_himem bx).buf]
546 cmp eax,edx ; if (m->fallback != m->buf)
547 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
548 ifdef LARGE_IMAGES
549 mov ecx,[(image_himem bx).size]
550 memcpy_imagez:
551 push ecx
552 else
553 push [(image_himem bx).size]
554 endif
555 push eax
556 push 0
557 call_memcpy32:
558 push edx
559 else
560 mov ax,[word ((image_himem bx).fallback)]
561 mov dx,[word ((image_himem bx).fallback)+2]
562 mov cx,[word ((image_himem bx).buf)]
563 cmp ax,cx ; if (m->fallback != m->buf)
564 jnz @@do
565 cmp dx,[word ((image_himem bx).buf)+2]
566 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
567 @@do:
568 push [word ((image_himem bx).size)+2]
569 push [word ((image_himem bx).size)]
570 push [word ((image_himem bx).buf)+2]
571 push cx
572 xor cx,cx
573 push cx
574 call_memcpy32:
575 push dx
576 push ax
577 ifdef LARGE_IMAGES
578 jmp @@memcpy
579 memcpy_imagez:
580 push ecx
581 push eax
582 push 0
583 push edx
584 endif
585 endif
586 @@memcpy:
587 extrn _memcpy32:near
588 call near _memcpy32
589 add sp,14
590 @@skip:
591 ret
593 endp _memcpy_image
595 ;***************************************************************
596 ;void storepage(u32 *dst, u16 src);
597 ;***************************************************************
598 global _storepage:near
599 proc _storepage near
601 pop ax ;caller return address
602 pop bx
603 pop cx
604 push cx
605 push bx
606 push ax
607 ifndef NO386
608 mov edx,[bx]
609 else
610 mov ax,[bx]
611 mov dx,[bx+2]
612 endif
613 storepage:
614 ifndef NO386
615 push 0
616 push 4096
617 push 0
618 else
619 xor bx,bx
620 push bx
621 mov bh,4096/256
622 push bx
623 xor bx,bx
624 push bx
625 endif
626 push cx
627 push ds
628 jmp call_memcpy32
630 endp _storepage
633 ifdef LARGE_IMAGES
634 ;***************************************************************
635 ;void reset_bufv(u32 *p);
636 ;***************************************************************
637 global _reset_bufv:near
638 proc _reset_bufv near
640 pop ax ;caller return address
641 pop bx
642 push bx
643 push ax
644 mov [curdata],bx
645 and [dword (data_himem bx).cacheidx],0
646 ret
648 endp _reset_bufv
650 ;***************************************************************
651 ;u32* prev_bufv();
652 ;u32* prev_bufv();
653 ;***************************************************************
654 global _prev_bufv:near
655 global _next_bufv:near
656 proc _prev_bufv near
658 stc
659 db 73h ; jnc
660 _next_bufv:
661 clc
662 sbb ax,ax
663 stc
664 rcl ax,1 ; -1/+1
665 xor ecx,ecx
666 push si
667 mov si,[curdata]
668 add ax,[(data_himem si).cacheidx]
669 test ax,0fc00h
670 jz @@gotpage
671 push ax ; FFFF / 0400
672 sar ax,8 ; FFFC / 0004
673 and al,0fch
674 add [(data_himem si).pageidx],ax
675 mov bx,[(data_himem si).pageidx]
676 lea bx,[(data_himem bx+si).page]
677 mov edx,ds
678 shl edx,4
679 lea cx,[(data_himem si).cache]
680 add edx,ecx
681 mov eax,[bx]
682 or eax,eax
683 jnz @@pageok
684 pop ax
685 xchg ax,bx
686 pop si
687 ret
688 @@pageok:
689 mov cx,4096
690 call memcpy_imagez ; get page
691 pop ax ; FFFF / 0400
692 cbw
693 shr ax,6 ; 03FF / 0000
694 @@gotpage:
695 mov [(data_himem si).cacheidx],ax
696 shl ax,2
697 xchg ax,bx
698 lea ax,[(data_himem bx+si).cache]
699 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
700 jnz @@notfirst2
701 xchg ax,si ; &first
702 @@notfirst2:
703 pop si
704 ret
706 endp _prev_bufv
707 endif
710 ;***************************************************************
711 ;void next_chunk(struct image_himem *di);
712 ;***************************************************************
713 proc next_chunk near
715 push si
716 mov bx,[(image_himem di).fd]
717 call close
718 ifndef NO386
719 xor eax,eax
720 else
721 xor ax,ax
722 endif
723 cwd
724 mov [(image_himem di).fd],ax
725 mov bx,[(image_himem di).state]
726 cmp al,[bx] ; ""
727 jz @@end
728 mov si,bx
729 @@scan:
730 lodsb
731 mov cx,si
732 cmp al,','
733 jz @@eos
734 cmp al,0
735 jnz @@scan
736 dec cx
737 @@eos:
738 mov [(image_himem di).state],cx
739 dec si
740 push [word si]
741 mov [byte si],dl ; set temp eos
742 call open
743 pop [word si] ; restore string
744 jc @@die
745 mov [(image_himem di).fd],ax
746 mov [(image_himem di).fd2close],ax
747 xchg ax,bx
748 mov ax,4202h ; SEEK_END
749 call lseek0
750 @@die:
751 mov bx,[(image_himem di).errmsg]
752 jc die
753 mov bx,[(image_himem di).fd]
754 ifndef NO386
755 push eax
756 call rewind
757 pop eax
758 @@end:
759 mov [(image_himem di).chunk_size],eax
760 else
761 push ax
762 push dx
763 call rewind
764 pop dx
765 pop ax
766 @@end:
767 mov [word (image_himem di).chunk_size],ax
768 mov [word ((image_himem di).chunk_size)+2],dx
769 endif
770 pop si
771 ret
773 endp next_chunk
776 ;***************************************************************
777 ;void open_image(const char *name, struct image_himem *m);
778 ;***************************************************************
779 global _open_image:near
780 proc _open_image near
782 arg fname :word, \
783 m :word = PARAM_SIZE
785 push bp
786 mov bp,sp
787 push si di
788 ifndef NO386
789 xor eax,eax ; 1st loop flag + eos
790 else
791 xor ax,ax ; 1st loop flag + eos
792 endif
793 mov di,[m]
794 cmp [(image_himem di).fd],ax
795 jnz @@alreadydone
796 ifndef NO386
797 mov [(image_himem di).size],eax ; m->size = 0L
798 else
799 mov [word (image_himem di).size],ax ; m->size = 0L
800 mov [word ((image_himem di).size)+2],ax
801 endif
802 mov [(image_himem di).next_chunk],offset next_chunk
803 mov si,[fname]
804 mov [(image_himem di).state],si
805 @@next:
806 push di
807 call [(image_himem di).next_chunk] ; m->next_chunk()
808 pop di
809 ifndef NO386
810 add eax,3
811 and al,0FCh
812 add [(image_himem di).size],eax ; m->size += m->chunk_size
813 or eax,eax
814 jnz @@next
815 else
816 mov cx,ax
817 or cx,dx
818 add ax,3
819 adc dx,0
820 and al,0FCh
821 add [word (image_himem di).size],ax ; m->size += m->chunk_size
822 adc [word ((image_himem di).size)+2],dx
823 inc cx ; jcxnz
824 loop @@next
825 endif
826 mov [(image_himem di).state],si
827 push di
828 call [(image_himem di).next_chunk] ; m->next_chunk()
829 pop di
830 @@alreadydone:
831 push ax
832 image_done:
833 pop ax
834 pop di si bp
835 ret
837 endp _open_image
840 ;***************************************************************
841 ;int read_image(struct image_himem *m, void* data, int sz);
842 ;***************************************************************
843 global _read_image:near
844 proc _read_image near
846 arg m :word, \
847 data :word, \
848 sz :word = PARAM_SIZE
850 push bp
851 mov bp,sp
852 push si di
853 ifndef NO386
854 push 0 ; return value
855 else
856 xor ax,ax
857 push ax
858 endif
859 mov di,[m]
860 @@loop:
861 ifndef NO386
862 xor ecx,ecx
863 mov cx,[word sz]
864 @@chksz:
865 mov eax,[(image_himem di).chunk_size]
866 cmp ecx,eax
867 jb @@szok
868 xchg eax,ecx
869 else
870 mov cx,[word sz]
871 @@chksz:
872 mov ax,[word (image_himem di).chunk_size]
873 cmp cx,ax
874 jb @@szok
875 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
876 jne @@szok
877 xchg ax,cx
878 endif
879 @@szok:
880 jcxz image_done
881 push cx
882 push [word data]
883 push [word di]
884 call _read
885 pop dx
886 pop bx
887 pop dx
888 jc image_done
889 add bx,ax
890 xor cx,cx
891 ifndef NO386
892 cwde ; ax < 8000h
893 sub [(image_himem di).chunk_size],eax
894 else
895 cwd ; ax < 8000h
896 sub [word (image_himem di).chunk_size],ax
897 sbb [word ((image_himem di).chunk_size)+2],dx
898 jnz @@fill
899 cmp [word (image_himem di).chunk_size],dx
900 endif
901 jnz @@fill
902 dec cx
903 @@fill:
904 test al,3
905 je @@filled
906 mov [bx],dl
907 inc bx
908 inc ax
909 jmp @@fill
910 @@filled:
911 ifndef NO386
912 sub [(image_himem di).remaining],eax
913 else
914 sub [word (image_himem di).remaining],ax
915 sbb [word ((image_himem di).remaining)+2],dx
916 endif
917 add [bp-4-2],ax
918 add [word data],ax
919 sub [word sz],ax
920 pushf
921 and cx,[(image_himem di).next_chunk]
922 jz @@same_chunk
923 push di
924 call cx ; m->next_chunk()
925 pop di
926 @@same_chunk:
927 popf
928 jnz @@loop
929 jmp image_done
931 endp _read_image
934 ;***************************************************************
935 ;unsigned long strtol(const char *s);
936 ;***************************************************************
937 global _strtol:near
938 proc _strtol near
940 ifndef NO386
941 pop ax ;caller return address
942 pop cx ; s
943 push cx
944 push ax
945 xor ebx,ebx
946 push si
947 jcxz @@end
948 mov si,cx
949 xor ecx,ecx
950 xor eax,eax
951 lodsb
952 mov dx,ax
953 or al,20h
954 cmp al,'n' ; vga=normal
955 je @@vga
956 dec cx
957 cmp al,'e' ; vga=extended
958 je @@vga
959 dec cx
960 cmp al,'a' ; vga=ask
961 jne @@notvga
962 @@vga:
963 dec cx
964 xchg ax,cx
965 cwd
966 jmp @@popsiret
967 @@notvga:
968 mov cx,10 ; radix
969 xchg ax,dx
970 cmp al,'+'
971 je @@radixskip
972 cmp al,'-'
973 clc
974 jne @@radixkeep
975 stc
976 @@radixskip:
977 lodsb
978 @@radixkeep:
979 pushf
980 cmp al,'0'
981 jne @@radixok
982 mov cl,8
983 lodsb
984 or al,20h
985 cmp al,'x'
986 jne @@radixok
987 mov cl,16
988 @@strtollp:
989 lodsb
990 @@radixok:
991 or al,20h
992 sub al,'0'
993 jb @@endstrtol
994 cmp al,9
995 jbe @@digitok
996 cmp al,'a'-'0'
997 jb @@endstrtol
998 sub al,'a'-'0'-10
999 @@digitok:
1000 cmp al,cl
1001 jae @@endstrtol
1002 xchg eax,ebx
1003 mul ecx
1004 add eax,ebx
1005 xchg eax,ebx
1006 jmp @@strtollp
1007 @@endstrtol:
1008 mov cl,10
1009 cmp al,'k'-'a'+10
1010 je @@shift
1011 mov cl,20
1012 cmp al,'m'-'a'+10
1013 je @@shift
1014 mov cl,30
1015 cmp al,'g'-'a'+10
1016 jne @@noshift
1017 @@shift:
1018 shl ebx,cl
1019 @@noshift:
1020 popf
1021 jnc @@end
1022 neg ebx
1023 @@end:
1024 push ebx
1025 pop ax
1026 pop dx
1027 @@popsiret:
1028 pop si
1029 else
1030 pop ax ;caller return address
1031 pop cx ; s
1032 push cx
1033 push ax
1034 push si
1035 push di
1036 xor ax,ax
1037 cwd
1038 jcxz @@goend
1039 xchg ax,di
1040 mov si,cx
1041 lodsb
1042 mov bx,ax
1043 or al,20h
1044 mov cx,-1
1045 cmp al,'n' ; vga=normal
1046 je @@vga
1047 dec cx
1048 cmp al,'e' ; vga=extended
1049 je @@vga
1050 dec cx
1051 cmp al,'a' ; vga=ask
1052 jne @@notvga
1053 @@vga:
1054 xchg ax,cx
1055 @@goend:
1056 jmp @@popdisiret
1057 @@notvga:
1058 mov cx,10 ; radix
1059 xchg ax,bx
1060 cmp al,'+'
1061 je @@radixskip
1062 cmp al,'-'
1063 clc
1064 jne @@radixkeep
1065 stc
1066 @@radixskip:
1067 lodsb
1068 @@radixkeep:
1069 pushf
1070 cmp al,'0'
1071 jne @@radixok
1072 mov cl,8
1073 lodsb
1074 mov al,20h
1075 cmp al,'x'
1076 jne @@radixok
1077 mov cl,16
1078 @@strtollp:
1079 lodsb
1080 @@radixok:
1081 or al,20h
1082 sub al,'0'
1083 jb @@endstrtol
1084 cmp al,9
1085 jbe @@digitok
1086 cmp al,'a'-'0'
1087 jb @@endstrtol
1088 sub al,'a'-'0'-10
1089 @@digitok:
1090 cmp al,cl
1091 jae @@endstrtol
1093 push ax
1094 push si
1095 push dx
1096 xchg ax,di
1097 mul cx
1098 xchg ax,di
1099 xchg ax,dx
1100 xchg ax,si
1101 pop ax
1102 mul cx
1103 add ax,si
1104 pop si
1105 xchg ax,dx
1106 pop ax
1107 mov ah,0
1108 add di,ax
1109 adc dx,0
1111 jmp @@strtollp
1112 @@endstrtol:
1113 mov cl,10
1114 cmp al,'k'-'a'+10
1115 je @@shift
1116 mov cl,20
1117 cmp al,'m'-'a'+10
1118 je @@shift
1119 mov cl,30
1120 cmp al,'g'-'a'+10
1121 jne @@noshift
1122 @@shift:
1123 rcl di,1
1124 shl dx,1
1125 loop @@shift
1126 @@noshift:
1127 popf
1128 jnc @@end
1129 not dx
1130 neg di
1131 jne @@end
1132 inc dx
1133 @@end:
1134 xchg ax,di
1135 @@popdisiret:
1136 pop di
1137 pop si
1138 endif
1139 ret
1141 endp _strtol
1144 ifdef NO386
1145 ;***************************************************************
1146 ;u16 topseg();
1147 ;***************************************************************
1148 global _topseg:near
1149 proc _topseg near
1151 int 12h
1152 jnc @@max640k
1153 mov ax,640 ; 9000
1154 @@max640k:
1155 dec ax
1156 and al,0C0h
1157 mov cl,6
1158 shl ax,cl
1159 ret
1161 endp _topseg
1162 endif
1164 ends _TEXT
1166 end
1168 ;###### END OF FILE ############################################