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

linld: add quick boot switch
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Feb 18 08:56:43 2021 +0000 (2021-02-18)
parents 5c1ce90eb1d6
children c1844f1c4954
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %PAGESIZE 1000
6 %crefref
7 %noincl
8 %nomacs
9 ifdef NO386
10 p8086
11 else
12 p386
13 endif
15 group DGROUP _TEXT,_DATA,_BSS
16 assume cs:DGROUP,ds:DGROUP
18 segment _DATA byte public use16 'DATA'
20 loaderr db "Load failure",0
21 msg_hang db "Himem broken",0
22 vcpi_alloc_err db "VCPI"
23 global overflow:byte
24 overflow db "/"
25 msg_malloc db "Out of memory"
26 isorootofs dd 16*2048
28 ends _DATA
30 segment _BSS byte public use16 'BSS'
32 include "isostate.inc"
33 public _isostate
34 _isostate isostate <?>
35 org $-7
36 _xfer_buf db 4096 dup (?)
37 filecnt db ? ; in fact 0 minus file count...
38 nextfilename dw ?
40 ends _BSS
42 segment _TEXT byte public use16 'CODE'
44 ;***************************************************************
45 ;_fastcall void strcatb(bx:const char* a, ax:const char* b);
46 ;***************************************************************
47 global @strcatb$qpxzct1:near
48 proc @strcatb$qpxzct1 near
50 push si
51 xchg ax,si ; b
52 dec bx
53 @@catlp:
54 inc bx
55 cmp [byte bx],0 ; a=bx
56 jne @@catlp
57 db 0b8h,20h ; mov ax,??20h
58 @@cpylp:
59 lodsb
60 @@cpyhead:
61 mov [bx],al
62 inc bx
63 or al,al
64 jne @@cpylp
65 strend:
66 pop si
67 @ret:
68 ret
70 endp @strcatb$qpxzct1
73 p8086
75 opendos:
76 ifdef LONG_FILENAME
77 xchg ax,cx ; attributes
78 mov ax,716Ch
79 push bx si
80 mov si,bx
81 xor bx,bx ; R/O
82 cwd ; action = open
83 stc
84 int 21h
85 pop si dx
86 jnc openok
87 mov ax,3d00h ; read-only+compatibility
88 else
89 mov ah,3dh ; read-only+compatibility
90 mov dx,bx
91 endif
92 ;mov cl,0 ; attribute mask
93 call dos
94 jc openret
95 openok:
96 xchg ax,bx
97 mov ax,4202h
98 cwd
99 xor cx,cx
100 int 21h
101 mov [word _isostate.filesize],ax
102 mov [(word _isostate.filesize)+2],dx
103 xchg ax,bx
104 ;xor cx,cx
105 cwd
106 call seeksetpos0 ; filepos = 0
107 xchg ax,bx ; fd
108 openret:
109 ret
111 ;***************************************************************
112 ;_fastcall int open(bx:const char* name, int flags=O_RDONLY);
113 ;_fastcall int openargs(bx:const char* name, int flags=O_RDONLY);
114 ;***************************************************************
115 global openargs:near ; openargs(bx)
116 openargs:
117 cmp [byte bx],'@'
118 jne fail
119 inc bx
121 global @open$qpxzc:near
122 @open$qpxzc:
123 mov ax,[_isostate.fd]
124 or ax,ax
125 je opendos
126 openiso:
127 ifdef ISOHOOK
128 cmp [byte bx],'!'
129 je @readmenu$qv
130 endif
131 extrn @_isoopen$qv:near
132 mov [word _isostate.filename2open],bx
133 jmp @_isoopen$qv ; filepos = 0
136 ;***************************************************************
137 ;_fastcall int fileexist(bx:const char* name);
138 ;***************************************************************
139 global @fileexist$qpxzc:near
140 @fileexist$qpxzc:
141 call @open$qpxzc
142 jc fail
144 ;***************************************************************
145 ;_fastcall int close(ax:int fd);
146 ;***************************************************************
147 global @close$qi:near
148 proc @close$qi near
150 global close:near ; close(ax)
151 close:
152 mov bh,3Eh
153 mov cx,[_isostate.fd]
154 jcxz dosbx
155 jmp fail
157 endp @close$qi
160 ;***************************************************************
161 ;_fastcall int readrm(si:struct himem *m, ax:int sz);
162 ;***************************************************************
163 global @readrm$qp11image_himemi:near
164 @readrm$qp11image_himemi:
165 xchg ax,dx ; sz
166 mov ax,[si] ; fd
167 mov bx,[si-2] ; data
168 proc @read$qipvi near
170 @read$dxbxax:
171 xchg ax,bx ; fd
172 @read$dxaxbx:
173 xchg ax,dx ; data
174 xchg ax,cx ; sz
175 global @read$cxdxbx:near
176 @read$cxdxbx:
177 push bx
178 mov bx,offset _isostate.filepos
179 push cx
180 mov cx,[bx-4] ; filesize
181 sub cx,[bx] ; filepos
182 mov ax,[bx-2]
183 sbb ax,[bx+2]
184 pop ax
185 ja @@axok
186 ;je @@rem
187 ;xor ax,ax
188 @@rem:
189 cmp cx,ax
190 jb @@cxok
191 @@axok:
192 xchg ax,cx
193 @@cxok:
194 add [bx],cx
195 adc [(word bx)+2],0
196 pop bx
197 readfd:
198 mov ah,3Fh
199 ;jcxz fail
200 dos:
201 int 21h
202 jnc doret
203 fail:
204 stc
205 failifc:
206 sbb ax,ax ; ax=-1 CF
207 doret:
208 ret
210 endp @read$qipvi
212 ;***************************************************************
213 ;_fastcall long rewind(ax:int fd);
214 ;***************************************************************
216 global @rewind$qi:near ; fd=ax
217 proc @rewind$qi near
219 rewind:
220 mov bx,offset _isostate.fileofs
221 jmp lseek
223 endp @rewind$qi
226 ifdef ISOHOOK
227 ;***************************************************************
228 ;_fastcall void readmenu(void);
229 ;***************************************************************
230 proc @readmenu$qv near
232 mov dx,18
233 xor cx,cx
234 call seeksetpos0 ; filepos = 0
235 mov dx,offset _isostate.filemod
236 ; //magic = x->filemod;
237 mov cl,10
238 call readfd ; // read x->filemod + x->fileofs & x->filesize
239 mov bx,offset _isostate.fileofs
240 ; x->fileofs = 0x7FF0 - (x->filesize &= 0xFFFF);
241 mov ax,7FF0h
242 cwd
243 mov [word bx+6],dx
244 sub ax,[bx+4]
245 mov [word bx+2],dx
246 mov [bx],ax
247 call isolseek ; filepos = 0
248 xchg ax,bx ; fd
249 ret
251 endp @readmenu$qv
252 endif
254 ;***************************************************************
255 ;_fastcall void isolseek(bx:const unsigned long *offset);
256 ;***************************************************************
257 global @isolseek$qpxul:near
258 proc @isolseek$qpxul near
260 isolseek:
261 mov ax,[_isostate.fd]
262 lseek:
263 les dx,[dword bx]
264 mov cx,es
265 seeksetpos0:
266 xor bx,bx
267 mov [word _isostate.filepos],bx
268 mov [(word _isostate.filepos)+2],bx
269 mov bh,42h ; bx=fd cx:dx=offset al=whence
270 dosbx:
271 xchg ax,bx
272 jmp dos
274 endp @isolseek$qpxul
276 ;***************************************************************
277 ;_fastcall int isoreadsector(bx:const unsigned long *offset);
278 ;_fastcall int isoreadrootsector(void);
279 ;***************************************************************
280 global @isoreadrootsector$qv:near
281 @isoreadrootsector$qv:
282 mov bx,offset isorootofs
283 global @isoreadsector$qpxul:near
284 proc @isoreadsector$qpxul near
286 call isolseek ; filepos = 0
287 jc fail
288 mov dh,10
289 mov ax,offset _isostate.buffer
290 jmp @read$dxaxbx ; read(fd,buffer,2560+)
292 endp @isoreadsector$qpxul
295 ifdef ISOHOOK
296 ;***************************************************************
297 ;_fastcall int strhead(bx:const char* a, ax:const char* b);
298 ;***************************************************************
299 global @strhead$qpxzct1:near
300 proc @strhead$qpxzct1 near
302 @@loop:
303 xchg ax,bx
304 mov dl,[bx] ; dl = *b++
305 inc bx
306 xchg ax,bx
307 or dl,dl ; clear C
308 jz failifc ; return 0
309 xor dl,[bx] ; dl -= *a++
310 jne fail ; return -1
311 inc bx
312 jmp @@loop
314 endp @strhead$qpxzct1
317 ;***************************************************************
318 ;_fastcall int strcmp(bx:const char* a, ax:const char* b);
319 ;***************************************************************
320 global @strcmp$qpxzct1:near
321 proc @strcmp$qpxzct1 near
323 call @strhead$qpxzct1
324 jne fail ; return -1
325 xor dl,[bx] ; clear C
326 jne fail ; return -1
327 jmp failifc ; return 0
329 endp @strcmp$qpxzct1
331 else
333 ;***************************************************************
334 ;_fastcall int strcmp(bx:const char* a, ax:const char* b);
335 ;***************************************************************
336 global @strcmp$qpxzct1:near
337 proc @strcmp$qpxzct1 near
339 @@loop:
340 xchg ax,bx
341 mov dl,[bx] ; dl = *b++
342 inc bx
343 xchg ax,bx
344 xor dl,[bx] ; dl ^= *a++
345 jne fail ; return -1
346 inc bx
347 or dl,dl ; clear C
348 jz failifc ; return 0
349 jmp @@loop
351 endp @strcmp$qpxzct1
352 endif
354 ;***************************************************************
355 ;_fastcall const char **argstr(bx:const char *s, ax:const char keywords[], dx:const char **var);
356 ;_fastcall unsigned long *argnum(bx:char *s, ax:const char keywords[], dx:unsigned long *var);
357 ;***************************************************************
358 global @argstr$qpxzcxt1ppxzc:near
359 proc @argstr$qpxzcxt1ppxzc near
361 mov cl,2
362 db 0a9h ; test ax,#
363 global @argnum$qpzcxpxzcpul:near
364 @argnum$qpzcxpxzcpul:
365 mov cl,4
366 push bx
367 xchg ax,bx ; keywords -> bx
368 xchg ax,cx ; s -> cx
369 cbw ; argstr:0002 argnum:0004
370 xchg ax,dx ; vars -> ax
371 push si di
372 xchg ax,di ; vars => di
373 dec bx
374 @@testalt:
375 sub di,dx
376 @@loop:
377 mov si,cx ; s
378 add di,dx
379 @@match:
380 inc bx ; keywords++
381 lodsb ; *s++
382 or al,20h ; locase
383 cmp al,[bx]
384 je @@match
385 cmp al,'/' ; 2f
386 jne @@notopt
387 cmp [byte bx],'-'
388 je @@match
389 @@notopt:
390 cmp [byte bx],'|'
391 je @@test
392 cmp [byte bx],dh
393 je @@test
394 mov al,-1
395 inc bx
396 jmp @@notopt
397 @@test:
398 or al,al ; 1st loop ?
399 jns @@testal
400 cmp [byte bx],dh
401 jne @@loop
402 @@testal:
403 cmp al,'*'
404 je @@setnum
405 cmp al,'='
406 ;je @@found
407 ;cmp al,0 ; eos, si=next argv
408 xchg ax,cx ; return s if failure
409 jne @@nokeyword
410 @@found:
411 dec dx
412 dec dx
413 je @@done
414 call @strtol$qpxzc
415 @@setnum:
416 xchg ax,si
417 mov [di+2],dx
418 @@done:
419 mov [di],si
420 xchg ax,di
421 @@nokeyword:
422 pop di si bx
423 ret
425 endp @argstr$qpxzcxt1ppxzc
427 ;***************************************************************
428 ;_fastcall void puts(bx:const char* s):
429 ;***************************************************************
430 global @puts$qpxzc:near
432 ; global puts:near ; puts(bx)
433 @putsz:
434 call @putc
435 @puts$qpxzc:
436 puts:
437 mov dl,[bx]
438 inc bx
439 or dl,dl
440 jne @putsz
441 mov dl,10
442 @putc:
443 cmp dl,10
444 jne @putcz
445 call @putcz2
446 @putcz2:
447 xor dl,7 ; 10^13 1010^1101
448 @putcz:
449 mov ah,2
450 do_int21h:
451 int 21h
452 ret
455 include "himem.inc"
457 ;***************************************************************
458 ;_fastcall char* malloc_or_die(ax:unsigned size);
459 ;***************************************************************
460 xchg_heap_top:
461 xchg ax,[bx]
462 ret
464 proc @malloc_or_die$qui near
466 malloc_or_die: ; ax = malloc_or_die(ax)
467 extrn _heap_top
468 mov bx,offset _heap_top
469 add ax,[bx]
470 jnc xchg_heap_top
471 mov bx,offset msg_malloc
473 endp @malloc_or_die$qui
476 ;***************************************************************
477 ;_fastcall int die(bx:const char* msg);
478 ;int exit(ax:int status);
479 ;int abort(void);
480 ;***************************************************************
481 global @die$qpxzc:near
482 proc @die$qpxzc near
483 @die$qpxzc:
484 global die:near ; die(bx)
485 die:
486 call puts
487 global @exit$qv:near
488 @exit$qv:
489 _exit:
490 extrn _imgs:image_himem
491 mov cx,[(word _imgs.buf)+2] ; no_exit ?
492 mov ah,4Ch
493 jcxz do_int21h
494 mov bx, offset msg_hang
495 call puts
496 ; global _abort:near
497 _abort:
498 cli
499 hlt
500 jmp _abort
502 endp @die$qpxzc
504 ;***************************************************************
505 ;_fastcall void open_image(si:struct image_himem *m, ax:const char *name);
506 ;***************************************************************
508 global @open_image$qp11image_himempxzc:near
509 proc @open_image$qp11image_himempxzc near
511 mov [(image_himem si).state],ax
512 push ax
513 @@next:
514 call next_chunk
515 ifndef NO386
516 add eax,3
517 and al,0FCh
518 add [(image_himem si).size],eax ; m->size += m->chunk_size
519 or eax,eax
520 else
521 add ax,3
522 adc dx,0
523 and al,0FCh
524 add [word (image_himem si).size],ax ; m->size += m->chunk_size
525 adc [word ((image_himem si).size)+2],dx
526 or ax,dx
527 endif
528 jnz @@next
529 pop [(image_himem si).state]
531 endp @open_image$qp11image_himempxzc
534 ;***************************************************************
535 ;static long next_chunk(struct image_himem *si);
536 ;***************************************************************
537 proc next_chunk near
539 ifndef NO_CLOSE
540 mov ax,[(image_himem si).fd]
541 call close
542 endif
543 ifndef NO386
544 xor eax,eax
545 else
546 xor ax,ax
547 cwd
548 endif
549 mov [(image_himem si).fd],ax
550 mov bx,[(image_himem si).state]
551 cmp al,[bx] ; ""
552 jz @@end
553 dec bx
554 push di
555 @@scan:
556 inc bx
557 mov al,[bx]
558 mov di,bx
559 or al,al
560 jz @@eos
561 sub al,','
562 jnz @@scan
563 inc bx
564 @@eos:
565 xchg [(image_himem si).state],bx ; set start of string
566 mov [current_file],bx
567 xchg [di],ax ; set temp eos (ax == 0)
568 push ax
569 call @open$qpxzc
570 pop [word di] ; restore string
571 pop di
572 jnc @@opened
573 loadfailure:
574 ;***************************************************************
575 ;_fastcall void loadfailure(void);
576 ;***************************************************************
577 global @loadfailure$qv:near
578 @loadfailure$qv:
579 mov bx,0
580 org $-2
581 current_file dw ?
582 call puts
583 mov bx,offset loaderr
584 jmpdie:
585 jmp die
586 @@opened:
587 mov [(image_himem si).fd],ax
588 ifndef NO_CLOSE
589 mov [(image_himem si).fd2close],ax
590 endif
591 ifndef NO386
592 mov eax,[_isostate.filesize]
593 @@end:
594 mov [(image_himem si).chunk_size],eax
595 else
596 mov ax,[word _isostate.filesize]
597 mov dx,[(word _isostate.filesize)+2]
598 @@end:
599 mov [word (image_himem si).chunk_size],ax
600 mov [word ((image_himem si).chunk_size)+2],dx
601 endif
602 ret
604 endp next_chunk
606 ;***************************************************************
608 struc data_himem ;struct data_himem {
609 first dd ? ; 0 u32 first; *must* be the first one
610 cacheidx dw ? ; 4 int cacheidx; quad *
611 pageidx dw ? ; 6 int pageidx; byte *
612 cache dd 1024 dup(?) ; 8 int cache;
613 page dd 1024 dup(?) ;4104 int page;
614 ends data_himem ;};
616 ;***************************************************************
617 ;_fastcall u32* malloc_bufv_or_die(si:struct image_himem *m);
618 ;***************************************************************
619 global @malloc_bufv_or_die$qp11image_himem:near
620 proc @malloc_bufv_or_die$qp11image_himem near
622 p386
623 push si
624 ;mov ecx,[(image_himem si).size]
625 ;shr ecx,20 ; pages index size = size >> 20
626 ;mov ax,cx
627 ;add ax,size data_himem-4096
628 mov ax,size data_himem
629 call malloc_or_die
630 ;mov cx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
631 mov ecx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
632 add ecx,[(image_himem si).size]
633 shr ecx,12
634 mov [curdata],ax
635 mov [(image_himem si).bufv],ax ; update m->bufv
636 xchg ax,si
637 @@vcpi_alloc:
638 mov ax,0DE04h ; allocate a 4K page => EDX
639 int 67h
640 or ah,ah
641 mov bx,offset vcpi_alloc_err
642 jnz jmpdie
643 ; for (i = cnt-1; i >= 0; i--)
644 mov eax,ecx
645 dec eax
646 shl eax,12 ; i*_4k
647 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
648 mov bx,offset _imgs.fallback
649 push eax
650 add eax,[bx-2+2]
651 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
652 pop eax ; i*_4k
653 jbe @@pmok
654 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
655 jae @@vcpi_alloc
656 @@pmok:
657 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
658 add eax,[bx-2+2+size image_himem] ; +initrd.fallback
659 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
660 ja @@initrdok
661 mov eax,[bx-2+6+size image_himem] ; initrd.size
662 add eax,[bx-2+2+size image_himem] ; +initrd.fallback
663 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
664 @@ja_vcpi_alloc:
665 ja @@vcpi_alloc
666 @@initrdok:
667 cmp [(data_himem si).first],0
668 jne @@notfirst
669 mov [(data_himem si).first],edx
670 @@notfirst:
671 mov bx,[(data_himem si).cacheidx]
672 cmp bh,4
673 jae @@nextpage
674 shl bx,2
675 inc [(data_himem si).cacheidx]
676 mov [(data_himem bx+si).cache],edx ; cache[cacheidx++] = edx
677 loopd @@vcpi_alloc
678 mov [(data_himem bx+si).cache],ecx ; last is 0
679 @@nextpage:
680 and [(data_himem si).cacheidx],0
681 mov bx,[(data_himem si).pageidx]
682 mov [(data_himem bx+si).page],edx
683 add [(data_himem si).pageidx],4
684 push cx
685 lea cx,[(data_himem si).cache]
686 ifdef NO386
687 push edx
688 pop ax ; to dx:ax
689 pop dx
690 endif
691 call storepage ; storepage(edx,cx)
692 pop cx
693 or ecx,ecx ; clear C
694 jnz @@ja_vcpi_alloc
695 mov [dword (data_himem si).cacheidx],ecx
696 xchg ax,si
697 pop si
698 ret
699 ifdef NO386
700 p8086
701 endif
703 endp @malloc_bufv_or_die$qp11image_himem
706 ;***************************************************************
707 ;_fastcall void memcpy_image_initrd(si:struct image_himem *m);
708 ;_fastcall void memcpy_image_kernel(si:struct image_himem *m);
709 ;_fastcall void memcpy_image(bx:struct image_himem *m);
710 ;***************************************************************
711 global @memcpy_image_initrd$qv:near
712 @memcpy_image_initrd$qv:
713 lea bx,[si+size image_himem]
714 db 0A9h ; test ax,imm
715 global @memcpy_image_kernel$qv:near
716 @memcpy_image_kernel$qv:
717 mov bx,si
718 proc @memcpy_image$qp11image_himem near
720 ifndef NO386
721 mov edx,[(image_himem bx).fallback]
722 mov eax,[(image_himem bx).buf]
723 cmp eax,edx ; if (m->fallback != m->buf)
724 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
725 mov ecx,[(image_himem bx).size]
726 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
727 push ecx
728 push eax
729 push 0
730 call_memcpy32:
731 push edx
732 else
733 les ax,[dword ((image_himem bx).fallback)]
734 mov dx,es
735 les cx,[dword ((image_himem bx).buf)]
736 cmp ax,cx ; if (m->fallback != m->buf)
737 jnz @@do
738 cmp dx,[word ((image_himem bx).buf)+2]
739 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
740 @@do:
741 push [word ((image_himem bx).size)+2]
742 push [word ((image_himem bx).size)]
743 push es ; [word ((image_himem bx).buf)+2]
744 push cx ; [word ((image_himem bx).buf)]
745 xor cx,cx
746 push cx
747 call_memcpy32:
748 push dx ; push dx:ax
749 push ax
750 jmp @@memcpy
751 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
752 p386
753 push ecx
754 push eax
755 push 0
756 push edx
757 ifdef NO386
758 p8086
759 endif
760 endif
761 @@memcpy:
762 extrn memcpy32:near
763 call near memcpy32
764 @@skip:
765 ret
767 endp @memcpy_image$qp11image_himem
769 ;***************************************************************
770 ;_fastcall void storepage(di:u32 *dst);
771 ;***************************************************************
772 global @storepage$qpul:near
773 proc @storepage$qpul near
775 ifndef NO386
776 mov edx,[di]
777 else
778 les ax,[dword di]
779 mov dx,es ; to dx:ax
780 endif
781 mov cx,offset _xfer_buf
782 storepage: ; storepage(edx,cx)
783 ifndef NO386
784 push 0
785 push 4096
786 push 0
787 else
788 xor bx,bx
789 push bx
790 mov bh,4096/256
791 push bx
792 xor bx,bx
793 push bx
794 endif
795 push cx
796 push ds
797 jmp call_memcpy32
799 endp @storepage$qpul
802 p386
803 ;***************************************************************
804 ;_fastcall void reset_bufv(di:u32 *p);
805 ;***************************************************************
806 global @reset_bufv$qpul:near
807 proc @reset_bufv$qpul near
809 mov [curdata],di
810 and [dword (data_himem di).cacheidx],0 ; and pageidx=0
811 ret
813 endp @reset_bufv$qpul
815 ;***************************************************************
816 ;u32* di=prev_bufv();
817 ;u32* di=prev_bufv();
818 ;***************************************************************
819 global _prev_bufv:near
820 global _next_bufv:near
821 proc _prev_bufv near
823 stc
824 db 73h ; jnc
825 _next_bufv:
826 clc
827 push si
828 mov bx,0
829 org $-2
830 curdata dw ?
831 sbb ax,ax
832 cmc
833 adc ax,[(data_himem bx).cacheidx] ; -1/+1
834 mov si,3ffh
835 and si,ax
836 mov [(data_himem bx).cacheidx],si
837 shl si,2
838 xor ecx,ecx
839 test ax,0fc00h
840 jz @@gotpage ; FFFF / 0400
841 xchg al,ah ; FFFC / 0004
842 and al,0fch
843 add [(data_himem bx).pageidx],ax
844 mov di,[(data_himem bx).pageidx]
845 lea di,[(data_himem bx+di).page]
846 mov edx,ds
847 shl edx,4
848 lea cx,[(data_himem bx).cache]
849 add edx,ecx
850 mov eax,[di]
851 or eax,eax
852 jz @@ret
853 mov cx,4096 ; get page
854 call memcpy_imagez ; memcpy_imagez(edx,eax,ecx)
855 @@gotpage:
856 lea ax,[(data_himem bx+si).cache]
857 or si,[(data_himem bx).pageidx] ; !pageidx && !cacheidx
858 jnz @@notfirst2
859 xchg ax,bx ; &first
860 @@notfirst2:
861 xchg ax,di
862 @@ret:
863 pop si
864 ret
866 endp _prev_bufv
868 ifdef NO386
869 p8086
870 endif
872 ;***************************************************************
873 ;_fastcall int read_image(si:struct image_himem *m);
874 ;***************************************************************
875 global @read_image$qp11image_himem:near
876 proc @read_image$qp11image_himem near
878 push di
879 mov di,4096
880 push di ; original size
881 @@loop:
882 ifndef NO386
883 movzx ecx,di
884 mov eax,[(image_himem si).chunk_size]
885 cmp ecx,eax
886 jb @@szok
887 else
888 mov cx,di
889 mov ax,[word (image_himem si).chunk_size]
890 cmp cx,ax
891 jb @@szok
892 cmp [word ((image_himem si).chunk_size)+2],0 ; hi m->chunk_size
893 jne @@szok
894 endif
895 xchg ax,cx
896 @@szok:
897 jcxz image_done
898 mov dx,offset _xfer_buf+4096
899 sub dx,di
900 mov bx,[si]
901 call @read$cxdxbx
902 jb image_done
903 xor cx,cx
904 cwd ; ax < 8000h
905 ifndef NO386
906 cwde ; ax < 8000h
907 sub [(image_himem si).chunk_size],eax
908 xchg eax,ebx
909 else
910 sub [word (image_himem si).chunk_size],ax
911 xchg ax,bx
912 sbb [word ((image_himem si).chunk_size)+2],dx
913 jnz @@fill
914 cmp [word (image_himem si).chunk_size],dx
915 endif
916 jnz @@fill
917 dec cx
918 @@fill:
919 test bl,3
920 je @@filled
921 mov [bx+_xfer_buf],dh
922 inc bx
923 jmp @@fill
924 @@filled:
925 ifndef NO386
926 sub [(image_himem si).remaining],ebx
927 else
928 sub [word (image_himem si).remaining],bx
929 sbb [word ((image_himem si).remaining)+2],dx
930 endif
931 sub di,bx
932 pushf
933 jcxz @@same_chunk
934 call next_chunk
935 @@same_chunk:
936 popf
937 jnz @@loop
938 image_done:
939 pop ax ; original size
940 sub ax,di
941 pop di
942 ret
944 endp @read_image$qp11image_himem
947 ;***************************************************************
948 ;_fastcall unsigned long strtol(const char *s);
949 ;***************************************************************
950 proc @strtol$qpxzc near
952 ifndef NO386
953 xor ecx,ecx
954 xor eax,eax
955 xor ebx,ebx
956 lodsb
957 or al,20h
958 cmp al,'a'
959 jb @@notvga
960 sub al,'o'
961 @@vgaloop:
962 dec cx
963 add al,6
964 jnb @@vgaloop ; vga=normal,extended,ask
965 @@vga:
966 dec cx
967 xchg ax,cx
968 cwd
969 jmp @@popsiret
970 @@notvga:
971 mov cl,10 ; radix
972 cmp al,'-'
973 jne @@radixkeep
974 lodsb
975 @@radixkeep:
976 pushf
977 cmp al,'0'
978 jne @@radixok
979 mov cl,8
980 lodsb
981 or al,20h
982 cmp al,'x'
983 jne @@radixok
984 mov cl,16
985 @@strtollp:
986 lodsb
987 @@radixok:
988 or al,20h
989 sub al,'0'
990 jb @@endstrtol
991 cmp al,9
992 jbe @@digitok
993 cmp al,'a'-'0'
994 jb @@endstrtol
995 sub al,'a'-'0'-10
996 @@digitok:
997 cmp al,cl
998 jae @@endstrtol
999 cbw
1000 cwde
1001 xchg eax,ebx
1002 mul ecx
1003 add ebx,eax
1004 jmp @@strtollp
1005 @@endstrtol:
1006 mov cl,10
1007 cmp al,'k'-'a'+10
1008 je @@shift
1009 mov cl,20
1010 cmp al,'m'-'a'+10
1011 je @@shift
1012 mov cl,30
1013 cmp al,'g'-'a'+10
1014 jne @@noshift
1015 @@shift:
1016 shl ebx,cl
1017 @@noshift:
1018 popf
1019 jnc @@end
1020 neg ebx
1021 @@end:
1022 push ebx
1023 pop ax
1024 pop dx
1025 @@popsiret:
1026 else
1027 xor bx,bx
1028 xor cx,cx
1029 xor dx,dx
1030 lodsb
1031 or al,20h
1032 cmp al,'a'
1033 jb @@notvga
1034 sub al,'o'
1035 @@vgaloop:
1036 dec cx
1037 add al,6
1038 jnb @@vgaloop ; vga=normal,extended,ask
1039 @@vga:
1040 xchg ax,cx
1041 ;cwd
1042 jmp @@end
1043 @@notvga:
1044 mov cl,10 ; radix
1045 cmp al,'-'
1046 jne @@radixkeep
1047 lodsb
1048 @@radixkeep:
1049 pushf
1050 cmp al,'0'
1051 jne @@radixok
1052 mov cl,8
1053 lodsb
1054 or al,20h
1055 cmp al,'x'
1056 jne @@radixok
1057 mov cl,16
1058 @@strtollp:
1059 lodsb
1060 @@radixok:
1061 or al,20h
1062 sub al,'0'
1063 jb @@endstrtol
1064 cmp al,9
1065 jbe @@digitok
1066 cmp al,'a'-'0'
1067 jb @@endstrtol
1068 sub al,'a'-'0'-10
1069 @@digitok:
1070 cmp al,cl
1071 jae @@endstrtol
1072 cbw
1074 push ax
1075 xchg ax,dx
1076 mul cx
1077 xchg ax,bx
1078 mul cx
1079 add dx,bx
1080 pop bx
1081 add bx,ax
1082 adc dx,0
1084 jmp @@strtollp
1085 @@endstrtol:
1086 mov cl,10
1087 cmp al,'k'-'a'+10
1088 je @@shift
1089 mov cl,20
1090 cmp al,'m'-'a'+10
1091 je @@shift
1092 mov cl,30
1093 cmp al,'g'-'a'+10
1094 @@shift:
1095 xchg ax,bx
1096 jne @@noshift
1097 extrn N_LXLSH@:near
1098 call N_LXLSH@
1099 @@noshift:
1100 popf
1101 jne @@end
1102 not dx
1103 neg ax
1104 jne @@end
1105 inc dx
1106 @@end:
1107 endif
1108 strtol_ret:
1109 ret
1111 endp @strtol$qpxzc
1114 ends _TEXT
1116 end
1118 ;###### END OF FILE ############################################