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

linld: 32 bits lseeks for tazboot
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Jan 05 17:23:23 2019 +0100 (2019-01-05)
parents d3d2a15d3d0d
children 57d97be431f4
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
20 extrn _bss_end
21 _heap_top dw _bss_end
22 msg_hang db "High mem corrupted - not exiting to DOS"
23 msg_lf db 10,0
24 vcpi_alloc_err db "VCPI "
25 msg_malloc db "malloc error",0
26 ifdef EXTRA
27 tazboot_cmd db "tazboot.cmd",0
28 endif
30 ends _DATA
32 segment _BSS byte public use16 'BSS'
34 _xfer_buf db 4096 dup (?)
35 global _no_exit:byte
36 _no_exit db ?
37 filecnt db ? ; in fact 0 minus file count...
38 nextfilename dw ?
39 ifdef LARGE_IMAGES
40 curdata dw ?
41 endif
42 ifdef EXTRA
43 ultoabuf db 12 dup (?)
44 endif
46 ends _BSS
48 segment _TEXT byte public use16 'CODE'
50 ;***************************************************************
51 ;_fastcall void strcpy(bx:const char* a, ax:const char* b);
52 ;_fastcall void strcat(bx:const char* a, ax:const char* b);
53 ;_fastcall void strcatb(bx:const char* a, ax:const char* b);
54 ;***************************************************************
55 global @strcatb$qpxzct1:near
56 proc @strcatb$qpxzct1 near
58 ifdef EXTRA
59 mov cl,7Fh
60 db 0bah ; mov dx,imm opcode
61 global @strcat$qpxzct1:near
62 @strcat$qpxzct1:
63 mov cl,80h
64 db 0bah ; mov dx,imm opcode
65 global @strcpy$qpxzct1:near
66 @strcpy$qpxzct1:
67 xor cx,cx
68 endif
69 push si
70 xchg ax,bx ; b
71 xchg ax,si ; a
72 ifdef EXTRA
73 jcxz @@nocat
74 endif
75 @@catlp:
76 lodsb ; a=si
77 or al,al
78 jne @@catlp
79 dec si
80 ifdef EXTRA
81 cmp bx,si
82 adc al,cl ; set S when bx != si or cl = 80
83 mov al,20h
84 jns @@cpyhead
85 endif
86 @@nocat:
87 @@cpylp:
88 mov al,[bx]
89 inc bx
90 @@cpyhead:
91 mov [si],al
92 inc si
93 or al,al
94 jne @@cpylp
95 strfound:
96 xchg ax,dx
97 strend:
98 pop si
99 ret
101 endp @strcatb$qpxzct1
104 ifdef EXTRA
105 p8086
106 ;***************************************************************
107 ;_fastcall char strstr(bx:const char* a, ax:const char* b);
108 ;***************************************************************
109 global @strstr$qpxzct1:near
110 proc @strstr$qpxzct1 near
112 xchg ax,cx ; b
113 mov dx,bx ; a
114 push si
115 @@loop:
116 xor ax,ax
117 mov si,dx
118 cmp [si],al ; *a
119 jz strend ; return ax = NULL
120 mov bx,cx
121 @@match:
122 or ah,[bx] ; *b
123 jz strfound
124 inc bx
125 lodsb
126 sub ah,al
127 jz @@match
128 inc dx
129 jmp @@loop
131 endp @strstr$qpxzct1
134 ;***************************************************************
135 ;_fastcall int strcmp(bx:const char* a, ax:const char* b);
136 ;***************************************************************
137 global @strcmp$qpxzct1:near
138 proc @strcmp$qpxzct1 near
140 push si
141 xchg ax,si
142 dec bx
143 @@lp:
144 inc bx
145 lodsb
146 sub al,[bx]
147 jnz @@out
148 or al,[bx]
149 jnz @@lp
150 @@out:
151 cbw
152 pop si
153 ret
155 endp @strcmp$qpxzct1
156 endif
159 ;***************************************************************
160 ;_fastcall void puts(bx:const char* s):
161 ;***************************************************************
162 global @puts$qpxzc:near
163 proc @puts$qpxzc near
165 ; global puts:near ; puts(bx)
166 puts:
167 call @@putsz
168 mov bx,offset msg_lf
169 mov dl,13
170 @@putcz:
171 mov ah,2
172 int 21h
173 @@putsz:
174 mov dl,[bx]
175 inc bx
176 or dl,dl
177 jne @@putcz ; ZF=1 (for malloc failure)
178 ret
180 endp @puts$qpxzc
184 ;***************************************************************
185 ;_fastcall int open(bx:const char* name, int flags=O_RDONLY);
186 ;***************************************************************
187 global openargs:near ; openargs(bx)
188 openargs:
189 cmp [byte bx],'@'
190 stc
191 jne fail
192 inc bx
194 global @open$qpxzc:near
195 proc @open$qpxzc near
197 global open:near ; open(bx)
198 open:
199 ifdef LONG_FILENAME
200 mov ax,716Ch
201 push bx di si
202 mov si,bx
203 xor bx,bx ; R/O
204 xor cx,cx ; attributes
205 xor di,di ; alias hint
206 cwd ; action = open
207 int 21h
208 pop si di bx
209 jnc doret
210 endif
211 mov ax,3d00h ; read-only+compatibility
212 ;mov cl,0 ; attribute mask
213 mov dx,bx
214 dos:
215 int 21h
216 chkc:
217 jnc doret
218 fail:
219 sbb ax,ax ; ax=-1 CF
220 cwd
221 doret:
222 ifndef NO386
223 push dx ; see next_chunk:lseek
224 push ax
225 pop eax
226 endif
227 ret
229 endp @open$qpxzc
232 ;***************************************************************
233 ;_fastcall int fileexist(bx:const char* name);
234 ;***************************************************************
235 global @fileexist$qpxzc:near
236 @fileexist$qpxzc:
237 call @open$qpxzc
238 jc fail
240 ;***************************************************************
241 ;_fastcall int close(ax:int fd);
242 ;***************************************************************
243 global @close$qi:near
244 proc @close$qi near
246 global close:near ; close(ax)
247 close:
248 xchg ax,bx
249 mov ah,3Eh
250 or bx,bx
251 jnz dos
252 ret
254 endp @close$qi
257 ;***************************************************************
258 ;_fastcall int read(ax:int fd, bx:void* data, dx:int sz);
259 ;_fastcall int write(ax:int fd, bx:const void* data, dx:int sz);
260 ;***************************************************************
261 global @read$qipvi:near
262 proc @read$qipvi near
264 ifdef WRITE
265 stc
266 db 0B0h ; mov al,im
267 global @write$qipvi:near
268 @write$qipvi:
269 clc
270 endif
271 @read$dxbxax:
272 xchg ax,bx ; fd
273 xchg ax,dx ; data
274 xchg ax,cx ; sz
275 ifdef WRITE
276 mov ah,40h
277 sbb ah,0
278 else
279 global @read$cxdxbx:near
280 @read$cxdxbx:
281 mov ah,3Fh
282 endif
283 jcxz fail
284 jmp dos
286 endp @read$qipvi
288 ;***************************************************************
289 ;_fastcall long lseekcur(ax:int fd, dx:int whence);
290 ;***************************************************************
292 global @lseekcur$qii:near ; fd=ax whence=dx
293 proc @lseekcur$qii near
295 mov cl,1
296 xchg ax,bx
297 xchg ax,dx
298 cwd
299 xchg ax,dx
300 xchg ax,cx
301 jmp lseek
302 rewind: ; rewind(ax)
303 mov bl,0
304 lseek0: ; lseek0(ax,bl=dir)
305 xor dx,dx
306 xor cx,cx
307 lseekset:
308 xchg ax,bx
309 lseek:
310 mov ah,42h ; bx=fd cx:dx=offset al=whence
311 jmp dos
313 endp @lseekcur$qii
315 ifdef EXTRA
317 ;typedef unsigned dirsizetype;
318 struc isostate ; struct isostate {
319 fd dw ? ; 0 int fd;
320 filemod dw ? ; 2 unsigned short filemod;
321 fileofs dd ? ; 4 unsigned long fileofs;
322 filesize dd ? ; 8 unsigned long filesize;
323 filename dw ? ;12 char *filename;
324 curdirsize dw ? ;14 dirsizetype curdirsize;
325 dirsize dw ? ;16 dirsizetype dirsize;
326 curdirofs dd ? ;18 unsigned long curdirofs;
327 dirofs dd ? ;22 unsigned long dirofs;
328 curpos dw ? ;26 unsigned curpos;
329 buffer db 2560 dup(?) ;28 char buffer[2048+512];
330 ends ; } isostate;
331 ;***************************************************************
332 ;_fastcall long isolseek(bx:const unsigned long *offset);
333 ;_fastcall long lseekset2(ax:int fd, bx:unsigned long* whence);
334 ;***************************************************************
335 global @isolseek$qpxul:near
336 proc @isolseek$qpxul near
338 isolseek:
339 extrn _isostate:isostate
340 mov ax,[_isostate.fd]
341 global @lseekset2$qipul
342 @lseekset2$qipul:
343 mov dx,[bx]
344 mov cx,[bx+2]
345 mov bl,0
346 jmp lseekset
348 endp @isolseek$qpxul
350 ;***************************************************************
351 ;_fastcall int isoreadsector(bx:const unsigned long *offset);
352 ;***************************************************************
353 global @isoreadsector$qpxul:near
354 proc @isoreadsector$qpxul near
356 call isolseek
357 jc doret
358 mov dx,2560
359 mov bx,offset _isostate.buffer
360 mov ax,[_isostate.fd]
361 jmp @read$dxbxax ; read(fd,buffer,2560)
363 endp @isoreadsector$qpxul
365 endif
368 ;***************************************************************
369 ;_fastcall int strhead(bx:const char* a, ax:const char* b);
370 ;***************************************************************
371 global @strhead$qpxzct1:near
372 proc @strhead$qpxzct1 near
374 @@loop:
375 xchg ax,bx
376 mov cl,[bx] ; cl = *b++
377 inc bx
378 or cl,cl ; clear C
379 jz fail ; return 0
380 xchg ax,bx
381 xor cl,[bx] ; cl -= *a++
382 inc bx
383 and cl,0dfh ; case insensitive
384 jz @@loop
385 ret ; return b (is not 0)
387 endp @strhead$qpxzct1
390 ;***************************************************************
391 ;_fastcall char* malloc_or_die(ax:unsigned size);
392 ;***************************************************************
393 global @malloc_or_die$qui:near
394 proc @malloc_or_die$qui near
396 xchg ax,cx ; size
397 global malloc_or_die:near ; malloc_or_die(cx)
398 malloc_or_die:
399 mov ax,[_heap_top] ; return value
400 mov bx,sp
401 add bh,-14h ; MIN_STACK=_1k+PAGE_SIZE
402 sub bx,ax ; can't overflow
403 cmp bx,cx
404 mov bx,offset msg_malloc
405 jb die
406 add [_heap_top],cx ; _BEG has zero'd heap
407 ret
409 endp @malloc_or_die$qui
412 ;***************************************************************
413 ;_fastcall int die(bx:const char* msg);
414 ;int exit();
415 ;int abort();
416 ;***************************************************************
417 global @die$qpxzc:near
418 proc @die$qpxzc near
419 @die$qpxzc:
420 global die:near ; die(bx)
421 die:
422 call puts
423 ; global _exit:near
424 _exit:
425 mov al,[_no_exit]
426 or al,al
427 jne @@hang
428 extrn exit:near
429 inc ax
430 jmp near exit
431 @@hang:
432 mov bx, offset msg_hang
433 call puts
434 ; global _abort:near
435 _abort:
436 cli
437 @@stop:
438 hlt
439 jmp @@stop
441 endp @die$qpxzc
443 struc image_himem ;struct image_himem {
444 fd dw ? ; 0 int fd;
445 fallback dd ? ; 2 u32 fallback;
446 size dd ? ; 6 u32 size;
447 remaining dd ? ;10 u32 remaining;
448 buf dd ? ;14 u32 buf;
449 bufv dw ? ;18 u32 *bufv;
450 errmsg dw ? ;20 char *errmsg;
451 chunk_size dd ? ;22 u32 chunk_size;
452 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
453 state dw ? ;28 u16 state;
454 fd2close dw ? ;30 u16 fd2close;
455 ends ;};
457 ;***************************************************************
458 ;static long next_chunk(struct image_himem *di);
459 ;***************************************************************
460 proc next_chunk near
462 push si
463 mov ax,[(image_himem di).fd]
464 call close
465 ifndef NO386
466 xor eax,eax
467 else
468 xor ax,ax
469 cwd
470 endif
471 mov [(image_himem di).fd],ax
472 mov bx,[(image_himem di).state]
473 cmp al,[bx] ; ""
474 jz @@end
475 mov si,bx
476 @@scan:
477 lodsb
478 mov cx,si
479 cmp al,','
480 jz @@eos
481 or al,al
482 jnz @@scan
483 dec cx
484 @@eos:
485 mov [(image_himem di).state],cx
486 dec si
487 push [word si]
488 mov [byte si],ah ; set temp eos
489 call open
490 pop [word si] ; restore string
491 jc @@die
492 mov [(image_himem di).fd],ax
493 mov [(image_himem di).fd2close],ax
494 mov bl,02h ; SEEK_END
495 call lseek0
496 @@die:
497 mov bx,[(image_himem di).errmsg]
498 jc die
499 ifndef NO386
500 push eax
501 mov ax,[(image_himem di).fd]
502 call rewind
503 pop eax
504 @@end:
505 mov [(image_himem di).chunk_size],eax
506 else
507 push ax
508 push dx
509 mov ax,[(image_himem di).fd]
510 call rewind
511 pop dx
512 pop ax
513 @@end:
514 mov [word (image_himem di).chunk_size],ax
515 mov [word ((image_himem di).chunk_size)+2],dx
516 endif
517 pop si
518 ret
520 endp next_chunk
523 ifdef LARGE_IMAGES
524 struc data_himem ;struct data_himem {
525 first dd ? ; 0 u32 first;
526 cacheidx dw ? ; 4 int cacheidx;
527 pageidx dw ? ; 6 int pageidx;
528 cache dd 1024 dup(?) ; 8 int cache;
529 page dd 1024 dup(?) ;4104 int page;
530 ends ;}; // size=8200
531 endif
533 ;***************************************************************
534 ;_fastcall u32* malloc_bufv_or_die(bx:struct image_himem *m);
535 ;***************************************************************
536 global @malloc_bufv_or_die$qp11image_himem:near
537 proc @malloc_bufv_or_die$qp11image_himem near
539 p386
540 push si
541 mov si,bx
542 ifdef LARGE_IMAGES
543 movzx ecx,[word ((image_himem si).size) + 2]
544 shr cx,4 ; pages index size = size >> 20
545 add cx,8+4096+8
546 call malloc_or_die
547 mov cx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
548 add ecx,[(image_himem si).size]
549 shr ecx,12
550 mov [curdata],ax
551 else
552 mov ecx,[(image_himem si).size]
553 dec ecx
554 shr ecx,12
555 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
556 push cx
557 inc cx ; cnt+1
558 shl cx,2 ; bufv => vcpi => vm86
559 ; our malloc zeroes allocated mem: bufv[cnt]=0;
560 ; Allocate pages, storing addrs in addrbuf
561 call malloc_or_die
562 pop cx
563 push ax
564 endif
565 mov [(image_himem si).bufv],ax
566 xchg ax,si
567 @@vcpi_alloc:
568 xor edx,edx
569 mov ax,0DE04h
570 int 67h
571 or ah,ah
572 mov bx,offset vcpi_alloc_err
573 jnz die
574 ; for (i = cnt-1; i >= 0; i--)
575 ifdef LARGE_IMAGES
576 mov eax,ecx
577 dec eax
578 else
579 mov ax,cx
580 dec ax
581 cwde
582 endif
583 shl eax,12 ; i*_4k
584 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
585 extrn _imgs
586 mov bx,offset _imgs+2
587 push eax
588 add eax,[bx-2+2]
589 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
590 pop eax ; i*_4k
591 jbe @@pmok
592 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
593 jae @@vcpi_alloc
594 @@pmok:
595 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
596 extrn _imgs
597 mov bx,offset _imgs+32+2
598 add eax,[bx-2+2] ; +initrd.fallback
599 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
600 ja @@initrdok
601 mov eax,[bx-2+6] ; initrd.size
602 add eax,[bx-2+2] ; +initrd.fallback
603 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
604 @@jnc_vcpi_alloc:
605 ja @@vcpi_alloc
606 @@initrdok:
607 ifdef LARGE_IMAGES
608 cmp [(data_himem si).first],0
609 jne @@notfirst
610 mov [(data_himem si).first],edx
611 @@notfirst:
612 mov bx,[(data_himem si).cacheidx]
613 cmp bh,4
614 jae @@nextpage
615 shl bx,2
616 inc [(data_himem si).cacheidx]
617 mov [(data_himem bx+si).cache],edx
618 loopd @@vcpi_alloc
619 mov [(data_himem bx+si).cache],ecx ; last is 0
620 @@nextpage:
621 and [(data_himem si).cacheidx],0
622 mov bx,[(data_himem si).pageidx]
623 mov [(data_himem bx+si).page],edx
624 add [(data_himem si).pageidx],4
625 push cx
626 lea cx,[(data_himem si).cache]
627 ifdef NO386
628 push edx
629 pop dx
630 pop ax
631 endif
632 call storepage ; storepage(edx,cx)
633 pop cx
634 or ecx,ecx ; clear C
635 jnz @@jnc_vcpi_alloc
636 mov [dword (data_himem si).cacheidx],ecx
637 xchg ax,si
638 else
639 mov [si],edx
640 lodsd ; si=+4
641 loop @@vcpi_alloc
642 pop ax
643 endif
644 pop si
645 ret
646 ifdef NO386
647 p8086
648 endif
650 endp @malloc_bufv_or_die$qp11image_himem
653 ;***************************************************************
654 ;_fastcall void memcpy_image(bx:struct image_himem *m);
655 ;***************************************************************
656 global @memcpy_image$qp11image_himem:near
657 proc @memcpy_image$qp11image_himem near
659 ifndef NO386
660 mov edx,[(image_himem bx).fallback]
661 mov eax,[(image_himem bx).buf]
662 cmp eax,edx ; if (m->fallback != m->buf)
663 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
664 ifdef LARGE_IMAGES
665 mov ecx,[(image_himem bx).size]
666 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
667 push ecx
668 else
669 push [(image_himem bx).size]
670 endif
671 push eax
672 push 0
673 call_memcpy32:
674 push edx
675 else
676 mov ax,[word ((image_himem bx).fallback)]
677 mov dx,[word ((image_himem bx).fallback)+2]
678 mov cx,[word ((image_himem bx).buf)]
679 cmp ax,cx ; if (m->fallback != m->buf)
680 jnz @@do
681 cmp dx,[word ((image_himem bx).buf)+2]
682 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
683 @@do:
684 push [word ((image_himem bx).size)+2]
685 push [word ((image_himem bx).size)]
686 push [word ((image_himem bx).buf)+2]
687 push cx
688 xor cx,cx
689 push cx
690 call_memcpy32:
691 push dx
692 push ax
693 ifdef LARGE_IMAGES
694 jmp @@memcpy
695 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
696 p386
697 push ecx
698 push eax
699 push 0
700 push edx
701 ifdef NO386
702 p8086
703 endif
704 endif
705 endif
706 @@memcpy:
707 extrn memcpy32:near
708 call near memcpy32
709 @@skip:
710 ret
712 endp @memcpy_image$qp11image_himem
714 ;***************************************************************
715 ;_fastcall void storepage(bx:u32 *dst);
716 ;***************************************************************
717 global @storepage$qpul:near
718 proc @storepage$qpul near
720 ifndef NO386
721 mov edx,[bx]
722 else
723 mov ax,[bx]
724 mov dx,[bx+2]
725 endif
726 mov cx,offset _xfer_buf
727 storepage: ; storepage(edx,cx)
728 ifndef NO386
729 push 0
730 push 4096
731 push 0
732 else
733 xor bx,bx
734 push bx
735 mov bh,4096/256
736 push bx
737 xor bx,bx
738 push bx
739 endif
740 push cx
741 push ds
742 jmp call_memcpy32
744 endp @storepage$qpul
747 ifdef LARGE_IMAGES
748 p386
749 ;***************************************************************
750 ;_fastcall void reset_bufv(bx:u32 *p);
751 ;***************************************************************
752 global @reset_bufv$qpul:near
753 proc @reset_bufv$qpul near
755 mov [curdata],bx
756 and [dword (data_himem bx).cacheidx],0
757 ret
759 endp @reset_bufv$qpul
761 ;***************************************************************
762 ;u32* prev_bufv();
763 ;u32* prev_bufv();
764 ;***************************************************************
765 global _prev_bufv:near
766 global _next_bufv:near
767 proc _prev_bufv near
769 stc
770 db 73h ; jnc
771 _next_bufv:
772 clc
773 push si
774 mov si,[curdata]
775 sbb ax,ax
776 cmc
777 adc ax,[(data_himem si).cacheidx] ; -1/+1
778 xor ecx,ecx
779 test ax,0fc00h
780 jz @@gotpage
781 push ax ; FFFF / 0400
782 sar ax,8 ; FFFC / 0004
783 and al,0fch
784 add [(data_himem si).pageidx],ax
785 mov bx,[(data_himem si).pageidx]
786 lea bx,[(data_himem bx+si).page]
787 mov edx,ds
788 shl edx,4
789 lea cx,[(data_himem si).cache]
790 add edx,ecx
791 mov eax,[bx]
792 or eax,eax
793 jnz @@pageok
794 pop ax
795 xchg ax,bx
796 pop si
797 ret
798 @@pageok:
799 mov cx,4096
800 call memcpy_imagez ; get page
801 pop ax ; FFFF / 0400
802 cbw
803 shr ax,6 ; 03FF / 0000
804 @@gotpage:
805 mov [(data_himem si).cacheidx],ax
806 shl ax,2
807 xchg ax,bx
808 lea ax,[(data_himem bx+si).cache]
809 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
810 jnz @@notfirst2
811 xchg ax,si ; &first
812 @@notfirst2:
813 pop si
814 ret
816 endp _prev_bufv
817 endif
819 ifdef NO386
820 p8086
821 endif
823 ;***************************************************************
824 ;_fastcall void open_image(bx:const char *name, ax:struct image_himem *m);
825 ;***************************************************************
826 global @open_image$qpxzcp11image_himem:near
827 proc @open_image$qpxzcp11image_himem near
829 push di
830 xchg ax,di
831 ifdef EXTRA
832 cmp [(image_himem di).fd],0 ; iso image/kernel ?
833 jnz @@alreadydone
834 endif
835 mov [(image_himem di).state],bx
836 push bx
837 ifdef EXTRA
838 cmp [(image_himem di).next_chunk],0 ; iso image/initrd ?
839 jnz @@next
840 endif
841 mov [(image_himem di).next_chunk],offset next_chunk
842 @@next:
843 call [(image_himem di).next_chunk] ; m->next_chunk()
844 ifndef NO386
845 add eax,3
846 and al,0FCh
847 add [(image_himem di).size],eax ; m->size += m->chunk_size
848 or eax,eax
849 else
850 add ax,3
851 adc dx,0
852 and al,0FCh
853 add [word (image_himem di).size],ax ; m->size += m->chunk_size
854 adc [word ((image_himem di).size)+2],dx
855 or ax,dx
856 endif
857 jnz @@next
858 pop [(image_himem di).state]
859 call [(image_himem di).next_chunk] ; m->next_chunk()
860 @@alreadydone:
861 pop di
862 ret
864 endp @open_image$qpxzcp11image_himem
867 ;***************************************************************
868 ;_fastcall int read_image(bx:struct image_himem *m);
869 ;***************************************************************
870 global @read_image$qp11image_himem:near
871 proc @read_image$qp11image_himem near
873 push si di
874 mov di,bx
875 mov si,4096
876 push si ; original size
877 @@loop:
878 ifndef NO386
879 movzx ecx,si
880 mov eax,[(image_himem di).chunk_size]
881 cmp ecx,eax
882 jb @@szok
883 else
884 mov cx,si
885 mov ax,[word (image_himem di).chunk_size]
886 cmp cx,ax
887 jb @@szok
888 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
889 jne @@szok
890 endif
891 xchg ax,cx
892 @@szok:
893 jcxz image_done
894 mov dx,offset _xfer_buf
895 mov bx,[di]
896 call @read$cxdxbx
897 jc image_done
898 xor cx,cx
899 cwd ; ax < 8000h
900 ifndef NO386
901 cwde ; ax < 8000h
902 sub [(image_himem di).chunk_size],eax
903 xchg eax,ebx
904 else
905 sub [word (image_himem di).chunk_size],ax
906 xchg ax,bx
907 sbb [word ((image_himem di).chunk_size)+2],dx
908 jnz @@fill
909 cmp [word (image_himem di).chunk_size],dx
910 endif
911 jnz @@fill
912 dec cx
913 @@fill:
914 test bl,3
915 je @@filled
916 mov [bx+_xfer_buf],dh
917 inc bx
918 jmp @@fill
919 @@filled:
920 ifndef NO386
921 sub [(image_himem di).remaining],ebx
922 else
923 sub [word (image_himem di).remaining],bx
924 sbb [word ((image_himem di).remaining)+2],dx
925 endif
926 sub si,bx
927 pushf
928 and cx,[(image_himem di).next_chunk]
929 jcxz @@same_chunk
930 call cx
931 @@same_chunk:
932 popf
933 jnz @@loop
934 image_done:
935 pop ax ; original size
936 sub ax,si
937 pop di si
938 ret
940 endp @read_image$qp11image_himem
943 ;***************************************************************
944 ;pascal unsigned long strtol(const char *s);
945 ;***************************************************************
946 global @strtol$qpxzc:near
947 proc @strtol$qpxzc near
949 pop ax
950 pop bx ; s
951 push ax
952 ifndef NO386
953 xor ebx,ebx
954 push si
955 jcxz @@end
956 mov si,cx
957 xor ecx,ecx
958 xor eax,eax
959 lodsb
960 mov dx,ax
961 or al,20h
962 cmp al,'n' ; vga=normal
963 je @@vga
964 dec cx
965 cmp al,'e' ; vga=extended
966 je @@vga
967 dec cx
968 cmp al,'a' ; vga=ask
969 jne @@notvga
970 @@vga:
971 dec cx
972 xchg ax,cx
973 cwd
974 jmp @@popsiret
975 @@notvga:
976 mov cx,10 ; radix
977 xchg ax,dx
978 cmp al,'+'
979 je @@radixskip
980 cmp al,'-'
981 clc
982 jne @@radixkeep
983 stc
984 @@radixskip:
985 lodsb
986 @@radixkeep:
987 pushf
988 cmp al,'0'
989 jne @@radixok
990 mov cl,8
991 lodsb
992 or al,20h
993 cmp al,'x'
994 jne @@radixok
995 mov cl,16
996 @@strtollp:
997 lodsb
998 @@radixok:
999 or al,20h
1000 sub al,'0'
1001 jb @@endstrtol
1002 cmp al,9
1003 jbe @@digitok
1004 cmp al,'a'-'0'
1005 jb @@endstrtol
1006 sub al,'a'-'0'-10
1007 @@digitok:
1008 cmp al,cl
1009 jae @@endstrtol
1010 xchg eax,ebx
1011 mul ecx
1012 add eax,ebx
1013 xchg eax,ebx
1014 jmp @@strtollp
1015 @@endstrtol:
1016 mov cl,10
1017 cmp al,'k'-'a'+10
1018 je @@shift
1019 mov cl,20
1020 cmp al,'m'-'a'+10
1021 je @@shift
1022 mov cl,30
1023 cmp al,'g'-'a'+10
1024 jne @@noshift
1025 @@shift:
1026 shl ebx,cl
1027 @@noshift:
1028 popf
1029 jnc @@end
1030 neg ebx
1031 @@end:
1032 push ebx
1033 pop ax
1034 pop dx
1035 @@popsiret:
1036 pop si
1037 else
1038 push si
1039 push di
1040 xor ax,ax
1041 cwd
1042 jcxz @@goend
1043 xchg ax,di
1044 mov si,cx
1045 lodsb
1046 mov bx,ax
1047 or al,20h
1048 mov cx,-1
1049 cmp al,'n' ; vga=normal
1050 je @@vga
1051 dec cx
1052 cmp al,'e' ; vga=extended
1053 je @@vga
1054 dec cx
1055 cmp al,'a' ; vga=ask
1056 jne @@notvga
1057 @@vga:
1058 xchg ax,cx
1059 @@goend:
1060 jmp @@popdisiret
1061 @@notvga:
1062 mov cx,10 ; radix
1063 xchg ax,bx
1064 cmp al,'+'
1065 je @@radixskip
1066 cmp al,'-'
1067 clc
1068 jne @@radixkeep
1069 stc
1070 @@radixskip:
1071 lodsb
1072 @@radixkeep:
1073 pushf
1074 cmp al,'0'
1075 jne @@radixok
1076 mov cl,8
1077 lodsb
1078 or al,20h
1079 cmp al,'x'
1080 jne @@radixok
1081 mov cl,16
1082 @@strtollp:
1083 lodsb
1084 @@radixok:
1085 or al,20h
1086 sub al,'0'
1087 jb @@endstrtol
1088 cmp al,9
1089 jbe @@digitok
1090 cmp al,'a'-'0'
1091 jb @@endstrtol
1092 sub al,'a'-'0'-10
1093 @@digitok:
1094 cmp al,cl
1095 jae @@endstrtol
1097 push ax
1098 push si
1099 push dx
1100 xchg ax,di
1101 mul cx
1102 xchg ax,di
1103 xchg ax,dx
1104 xchg ax,si
1105 pop ax
1106 mul cx
1107 add ax,si
1108 pop si
1109 xchg ax,dx
1110 pop ax
1111 mov ah,0
1112 add di,ax
1113 adc dx,0
1115 jmp @@strtollp
1116 @@endstrtol:
1117 mov cl,10
1118 cmp al,'k'-'a'+10
1119 je @@shift
1120 mov cl,20
1121 cmp al,'m'-'a'+10
1122 je @@shift
1123 mov cl,30
1124 cmp al,'g'-'a'+10
1125 jne @@noshift
1126 @@shift:
1127 rcl di,1
1128 shl dx,1
1129 loop @@shift
1130 @@noshift:
1131 popf
1132 jnc @@end
1133 not dx
1134 neg di
1135 jne @@end
1136 inc dx
1137 @@end:
1138 xchg ax,di
1139 @@popdisiret:
1140 pop di
1141 pop si
1142 endif
1143 strtol_ret:
1144 ret
1146 endp @strtol$qpxzc
1149 ifdef NO386
1150 ;***************************************************************
1151 ;u16 topseg();
1152 ;***************************************************************
1153 global _topseg:near
1154 proc _topseg near
1156 int 12h
1157 jnc @@max640k
1158 mov ax,640 ; 9000
1159 @@max640k:
1160 dec ax
1161 and al,0C0h
1162 mov cl,6
1163 shl ax,cl
1164 ret
1166 endp _topseg
1167 endif
1169 ifdef EXTRA
1170 p8086
1171 ;***************************************************************
1172 ;char *progname(void)
1173 ;***************************************************************
1174 global _progname:near
1175 proc _progname near
1177 push si di es
1178 mov ah,30h
1179 int 21h
1180 xor di,di
1181 cmp al,3
1182 mov ax,di
1183 jb @@skip
1184 ;mov es,[cs:2Ch]
1185 mov es,[di+2Ch]
1186 mov cx,sp ; big enough
1187 @@loop:
1188 repne
1189 scasb
1190 scasb
1191 jne @@loop
1192 inc di
1193 inc di
1194 mov si,di ; progname @es:di
1195 repne
1196 scasb
1197 mov cx,di
1198 sub cx,si ; progname len
1199 call malloc_or_die ; keep cx
1200 mov di,ax
1201 push ds
1202 push es
1203 pop ds
1204 pop es
1205 rep
1206 movsb
1207 push es
1208 pop ds
1209 @@skip:
1210 pop es di si
1211 ret
1213 endp _progname
1216 ;***************************************************************
1217 ;_fastcall void chdirname(bx:char *path)
1218 ;***************************************************************
1219 global @chdirname$qpzc:near
1220 proc @chdirname$qpzc near
1222 cmp [byte bx+1],3Ah ; ':'
1223 jne @@nodisk
1224 mov dl,20h
1225 or dl,[bx]
1226 sub dl,61h
1227 mov ah,0Eh
1228 int 21h
1229 inc bx
1230 inc bx
1231 @@nodisk:
1232 xor cx,cx
1233 @@next:
1234 mov al,[bx]
1235 cmp al,5Ch
1236 jne @@tsteos
1237 mov dx,bx
1238 inc cx
1239 @@tsteos:
1240 inc bx
1241 or al,al
1242 jnz @@next
1243 jcxz @@end
1244 mov bx,dx
1245 push [word bx]
1246 mov [bx],al
1247 ifdef LONG_FILENAME
1248 stc
1249 mov ax,713Bh ; chdir long filename (ds:dx)
1250 int 21h
1251 jnc @@chdirdone
1252 endif
1253 mov ah,3Bh ; chdir(ds:dx)
1254 int 21h
1255 @@chdirdone:
1256 pop [word bx]
1257 @@end:
1258 ret
1260 endp @chdirname$qpzc
1263 ;***************************************************************
1264 ;_fastcall char *ultoa(axdx:unsigned long n);
1265 ;***************************************************************
1266 global @ultoa$qul:near
1267 proc @ultoa$qul near
1269 xchg ax,cx
1270 xchg ax,dx ; AX:CX = n
1271 push si
1272 mov si,10
1273 mov bx,offset ultoabuf+11
1274 @@loop:
1275 dec bx
1276 xor dx,dx
1277 div si ; DX:AX = 0000:hi(n)
1278 xchg ax,cx ; CX = hi(n)/10
1279 div si ; DX:AX = hi(n)%10:lo(n)
1280 xchg ax,cx ; CX = lo(n/10)
1281 ; AX = hi(n)/10 = hi(n/10)
1282 mov [byte bx],'0'
1283 add [bx],dl ; DL = n%10
1284 mov dx,ax
1285 or dx,cx
1286 jnz @@loop
1287 xchg ax,bx
1288 pop si
1289 ret
1291 endp @ultoa$qul
1294 ;***************************************************************
1295 ;_fastcall unsigned long kver2ul(bx:char *kernel_version);
1296 ;***************************************************************
1297 global @kver2ul$qpzc:near
1298 proc @kver2ul$qpzc near
1300 push si
1301 mov si,bx
1302 xor bx,bx
1303 mov cx,304h
1304 @@number:
1305 xor ax,ax
1306 cwd
1307 @@digit:
1308 shl al,cl
1309 shl ax,cl
1310 lodsb
1311 sub al,30h
1312 cmp al,9
1313 jbe @@digit
1314 mov dl,bh
1315 mov bh,bl
1316 mov bl,ah
1317 dec ch
1318 jnz @@number
1319 xchg ax,bx
1320 pop si
1321 kver2ulret:
1322 ret
1324 endp @kver2ul$qpzc
1326 endif
1328 ;***************************************************************
1329 ;void try_default_args();
1330 ;***************************************************************
1331 ifdef EXTRA
1333 global _try_default_args:near
1334 proc _try_default_args near
1336 mov bx,offset tazboot_cmd
1337 call open
1338 jc kver2ulret
1339 mov cx,4096
1340 mov di,[_heap_top]
1341 extrn read_cmdline:near
1342 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1344 endp _try_default_args
1346 endif
1348 ends _TEXT
1350 end
1352 ;###### END OF FILE ############################################