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

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