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

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