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

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