wok view linld/stuff/src/CRTL.ASM @ rev 20528
linld: pascal convention calls
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Nov 09 16:37:55 2018 +0100 (2018-11-09) |
parents | 17c0ad41f5bf |
children | af959ebf1305 |
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 struc isostate ; struct isostate {
334 fd dw ? ; 0 int fd;
335 fileofs dd ? ; 2 unsigned long fileofs;
336 filesize dd ? ; 6 unsigned long filesize;
337 filemod dw ? ;10 unsigned short filemod;
338 filename dw ? ;12 char *filename;
339 dirofs dd ? ;14 unsigned long dirofs;
340 dirsize dd ? ;16 unsigned long dirsize;
341 curdirofs dd ? ;20 unsigned long curdirofs;
342 curdirsize dd ? ;24 unsigned long curdirsize;
343 curpos dd ? ;28 unsigned long curpos;
344 ends ; } isostate;
345 ;***************************************************************
346 ;pascal int isolseek(const unsigned long *offset);
347 ;***************************************************************
348 global @isolseek$qpxul:near
349 proc @isolseek$qpxul near
351 pop ax
352 pop bx
353 push ax
354 mov dx,[bx]
355 mov cx,[bx+2]
356 extrn _isostate:isostate
357 mov bx,[_isostate.fd]
358 call lseekset ; (bx=fd, sz=cx:dx)
359 and ax,dx
360 inc ax
361 ret
363 endp @isolseek$qpxul
364 endif
367 ;***************************************************************
368 ;pascal int strhead(const char* a,const char* b);
369 ;***************************************************************
370 global @strhead$qpxzct1:near
371 proc @strhead$qpxzct1 near
373 pop cx ;caller return address
374 pop ax ; b
375 pop bx ; a
376 push cx
377 @@loop:
378 xchg ax,bx
379 mov cl,[bx] ; cl = *b++
380 inc bx
381 or cl,cl ; clear C
382 jz fail ; return 0
383 xchg ax,bx
384 xor cl,[bx] ; cl -= *a++
385 inc bx
386 and cl,0dfh ; case insensitive
387 jz @@loop
388 ret ; return b (is not 0)
390 endp @strhead$qpxzct1
393 ;***************************************************************
394 ;pascal char* malloc_or_die(unsigned size);
395 ;***************************************************************
396 global @malloc_or_die$qui:near
397 proc @malloc_or_die$qui near
399 pop ax ;caller return address
400 pop cx ; size
401 push ax
402 global malloc_or_die:near ; malloc_or_die(cx)
403 malloc_or_die:
404 mov ax,[_heap_top] ; return value
405 mov bx,sp
406 add bh,-14h ; MIN_STACK=_1k+PAGE_SIZE
407 sub bx,ax ; can't overflow
408 cmp bx,cx
409 mov bx,offset msg_malloc
410 jb die
411 add [_heap_top],cx ; _BEG has zero'd heap
412 ret
414 endp @malloc_or_die$qui
417 ;***************************************************************
418 ;pascal int die(const char* msg);
419 ;int exit();
420 ;int abort();
421 ;***************************************************************
422 global @die$qpxzc:near
423 proc @die$qpxzc near
424 @die$qpxzc:
425 pop ax ;caller return address
426 pop bx ; s
427 ;push ax
428 global die:near ; die(bx)
429 die:
430 call puts
431 ; global _exit:near
432 _exit:
433 mov al,[_no_exit]
434 or al,al
435 jne @@hang
436 extrn exit:near
437 inc ax
438 jmp near exit
439 @@hang:
440 mov bx, offset msg_hang
441 call puts
442 ; global _abort:near
443 _abort:
444 cli
445 @@stop:
446 hlt
447 jmp @@stop
449 endp @die$qpxzc
451 struc image_himem ;struct image_himem {
452 fd dw ? ; 0 int fd;
453 fallback dd ? ; 2 u32 fallback;
454 size dd ? ; 6 u32 size;
455 remaining dd ? ;10 u32 remaining;
456 buf dd ? ;14 u32 buf;
457 bufv dw ? ;18 u32 *bufv;
458 errmsg dw ? ;20 char *errmsg;
459 chunk_size dd ? ;22 u32 chunk_size;
460 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
461 state dw ? ;28 u16 state;
462 fd2close dw ? ;30 u16 fd2close;
463 ends ;};
465 ;***************************************************************
466 ;long next_chunk(struct image_himem *di);
467 ;***************************************************************
468 proc next_chunk near
470 push si
471 mov bx,[(image_himem di).fd]
472 call close
473 ifndef NO386
474 xor eax,eax
475 else
476 xor ax,ax
477 cwd
478 endif
479 mov [(image_himem di).fd],ax
480 mov bx,[(image_himem di).state]
481 cmp al,[bx] ; ""
482 jz @@end
483 mov si,bx
484 @@scan:
485 lodsb
486 mov cx,si
487 cmp al,','
488 jz @@eos
489 or al,al
490 jnz @@scan
491 dec cx
492 @@eos:
493 mov [(image_himem di).state],cx
494 dec si
495 push [word si]
496 mov [byte si],ah ; set temp eos
497 call open
498 pop [word si] ; restore string
499 jc @@die
500 mov [(image_himem di).fd],ax
501 mov [(image_himem di).fd2close],ax
502 xchg ax,bx
503 mov ax,4202h ; SEEK_END
504 call lseek0
505 @@die:
506 mov bx,[(image_himem di).errmsg]
507 jc die
508 mov bx,[(image_himem di).fd]
509 ifndef NO386
510 push eax
511 call rewind
512 pop eax
513 @@end:
514 mov [(image_himem di).chunk_size],eax
515 else
516 push ax
517 push dx
518 call rewind
519 pop dx
520 pop ax
521 @@end:
522 mov [word (image_himem di).chunk_size],ax
523 mov [word ((image_himem di).chunk_size)+2],dx
524 endif
525 pop si
526 ret
528 endp next_chunk
531 ifdef LARGE_IMAGES
532 struc data_himem ;struct data_himem {
533 first dd ? ; 0 u32 first;
534 cacheidx dw ? ; 4 int cacheidx;
535 pageidx dw ? ; 6 int pageidx;
536 cache dd 1024 dup(?) ; 8 int cache;
537 page dd 1024 dup(?) ;4104 int page;
538 ends ;}; // size=8200
539 endif
541 ;***************************************************************
542 ;pascal u32* malloc_bufv_or_die(struct image_himem *m);
543 ;***************************************************************
544 global @malloc_bufv_or_die$qp11image_himem:near
545 proc @malloc_bufv_or_die$qp11image_himem near
547 p386
548 pop bx ;caller return address
549 pop ax
550 push bx
551 push si
552 xchg ax,si
553 ifdef LARGE_IMAGES
554 movzx ecx,[word ((image_himem si).size) + 2]
555 shr cx,4 ; pages index size = size >> 20
556 add cx,8+4096+8
557 call malloc_or_die
558 mov cx,4096+4095 ; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
559 add ecx,[(image_himem si).size]
560 shr ecx,12
561 mov [curdata],ax
562 else
563 mov ecx,[(image_himem si).size]
564 dec ecx
565 shr ecx,12
566 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
567 push cx
568 inc cx ; cnt+1
569 shl cx,2 ; bufv => vcpi => vm86
570 ; our malloc zeroes allocated mem: bufv[cnt]=0;
571 ; Allocate pages, storing addrs in addrbuf
572 call malloc_or_die
573 pop cx
574 push ax
575 endif
576 mov [(image_himem si).bufv],ax
577 xchg ax,si
578 @@vcpi_alloc:
579 xor edx,edx
580 mov ax,0DE04h
581 int 67h
582 or ah,ah
583 mov bx,offset vcpi_alloc_err
584 jnz die
585 ; for (i = cnt-1; i >= 0; i--)
586 ifdef LARGE_IMAGES
587 mov eax,ecx
588 dec eax
589 else
590 mov ax,cx
591 dec ax
592 cwde
593 endif
594 shl eax,12 ; i*_4k
595 ; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
596 extrn _imgs
597 mov bx,offset _imgs+2
598 push eax
599 add eax,[bx-2+2]
600 cmp eax,edx ; pm.fallback+i*_4k <= edx ?
601 pop eax ; i*_4k
602 jbe @@pmok
603 cmp edx,[bx-2+2] ; edx >= pm.fallback ?
604 jae @@vcpi_alloc
605 @@pmok:
606 ; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
607 extrn _imgs
608 mov bx,offset _imgs+32+2
609 add eax,[bx-2+2] ; +initrd.fallback
610 cmp eax,edx ; initrd.fallback+i*_4k > edx ?
611 ja @@initrdok
612 mov eax,[bx-2+6] ; initrd.size
613 add eax,[bx-2+2] ; +initrd.fallback
614 cmp eax,edx ; initrd.fallback+initrd.size > edx ?
615 @@jnc_vcpi_alloc:
616 ja @@vcpi_alloc
617 @@initrdok:
618 ifdef LARGE_IMAGES
619 cmp [(data_himem si).first],0
620 jne @@notfirst
621 mov [(data_himem si).first],edx
622 @@notfirst:
623 mov bx,[(data_himem si).cacheidx]
624 cmp bh,4
625 jae @@nextpage
626 shl bx,2
627 inc [(data_himem si).cacheidx]
628 mov [(data_himem bx+si).cache],edx
629 loopd @@vcpi_alloc
630 mov [(data_himem bx+si).cache],ecx ; last is 0
631 @@nextpage:
632 and [(data_himem si).cacheidx],0
633 mov bx,[(data_himem si).pageidx]
634 mov [(data_himem bx+si).page],edx
635 add [(data_himem si).pageidx],4
636 push cx
637 lea cx,[(data_himem si).cache]
638 ifdef NO386
639 push edx
640 pop dx
641 pop ax
642 endif
643 call storepage ; storepage(edx,cx)
644 pop cx
645 or ecx,ecx ; clear C
646 jnz @@jnc_vcpi_alloc
647 mov [dword (data_himem si).cacheidx],ecx
648 xchg ax,si
649 else
650 mov [si],edx
651 lodsd ; si=+4
652 loop @@vcpi_alloc
653 pop ax
654 endif
655 pop si
656 ret
657 ifdef NO386
658 p8086
659 endif
661 endp @malloc_bufv_or_die$qp11image_himem
664 ;***************************************************************
665 ;pascal void memcpy_image(struct image_himem *m);
666 ;***************************************************************
667 global @memcpy_image$qp11image_himem:near
668 proc @memcpy_image$qp11image_himem near
670 pop ax ;caller return address
671 pop bx
672 push ax
673 ifndef NO386
674 mov edx,[(image_himem bx).fallback]
675 mov eax,[(image_himem bx).buf]
676 cmp eax,edx ; if (m->fallback != m->buf)
677 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
678 ifdef LARGE_IMAGES
679 mov ecx,[(image_himem bx).size]
680 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
681 push ecx
682 else
683 push [(image_himem bx).size]
684 endif
685 push eax
686 push 0
687 call_memcpy32:
688 push edx
689 else
690 mov ax,[word ((image_himem bx).fallback)]
691 mov dx,[word ((image_himem bx).fallback)+2]
692 mov cx,[word ((image_himem bx).buf)]
693 cmp ax,cx ; if (m->fallback != m->buf)
694 jnz @@do
695 cmp dx,[word ((image_himem bx).buf)+2]
696 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
697 @@do:
698 push [word ((image_himem bx).size)+2]
699 push [word ((image_himem bx).size)]
700 push [word ((image_himem bx).buf)+2]
701 push cx
702 xor cx,cx
703 push cx
704 call_memcpy32:
705 push dx
706 push ax
707 ifdef LARGE_IMAGES
708 jmp @@memcpy
709 memcpy_imagez: ; memcpy_imagez(edx,eax,ecx)
710 p386
711 push ecx
712 push eax
713 push 0
714 push edx
715 ifdef NO386
716 p8086
717 endif
718 endif
719 endif
720 @@memcpy:
721 extrn memcpy32:near
722 call near memcpy32
723 @@skip:
724 ret
726 endp @memcpy_image$qp11image_himem
728 ;***************************************************************
729 ;pascal void storepage(u32 *dst, u16 src);
730 ;***************************************************************
731 global @storepage$qpulus:near
732 proc @storepage$qpulus near
734 pop ax ;caller return address
735 pop cx
736 pop bx
737 push ax
738 ifndef NO386
739 mov edx,[bx]
740 else
741 mov ax,[bx]
742 mov dx,[bx+2]
743 endif
744 storepage: ; storepage(edx,cx)
745 ifndef NO386
746 push 0
747 push 4096
748 push 0
749 else
750 xor bx,bx
751 push bx
752 mov bh,4096/256
753 push bx
754 xor bx,bx
755 push bx
756 endif
757 push cx
758 push ds
759 jmp call_memcpy32
761 endp @storepage$qpulus
764 ifdef LARGE_IMAGES
765 p386
766 ;***************************************************************
767 ;pascal void reset_bufv(u32 *p);
768 ;***************************************************************
769 global @reset_bufv$qpul:near
770 proc @reset_bufv$qpul near
772 pop ax ;caller return address
773 pop bx
774 push ax
775 mov [curdata],bx
776 and [dword (data_himem bx).cacheidx],0
777 ret
779 endp @reset_bufv$qpul
781 ;***************************************************************
782 ;u32* prev_bufv();
783 ;u32* prev_bufv();
784 ;***************************************************************
785 global _prev_bufv:near
786 global _next_bufv:near
787 proc _prev_bufv near
789 stc
790 db 73h ; jnc
791 _next_bufv:
792 clc
793 push si
794 mov si,[curdata]
795 sbb ax,ax
796 cmc
797 adc ax,[(data_himem si).cacheidx] ; -1/+1
798 xor ecx,ecx
799 test ax,0fc00h
800 jz @@gotpage
801 push ax ; FFFF / 0400
802 sar ax,8 ; FFFC / 0004
803 and al,0fch
804 add [(data_himem si).pageidx],ax
805 mov bx,[(data_himem si).pageidx]
806 lea bx,[(data_himem bx+si).page]
807 mov edx,ds
808 shl edx,4
809 lea cx,[(data_himem si).cache]
810 add edx,ecx
811 mov eax,[bx]
812 or eax,eax
813 jnz @@pageok
814 pop ax
815 xchg ax,bx
816 pop si
817 ret
818 @@pageok:
819 mov cx,4096
820 call memcpy_imagez ; get page
821 pop ax ; FFFF / 0400
822 cbw
823 shr ax,6 ; 03FF / 0000
824 @@gotpage:
825 mov [(data_himem si).cacheidx],ax
826 shl ax,2
827 xchg ax,bx
828 lea ax,[(data_himem bx+si).cache]
829 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
830 jnz @@notfirst2
831 xchg ax,si ; &first
832 @@notfirst2:
833 pop si
834 ret
836 endp _prev_bufv
837 endif
839 ifdef NO386
840 p8086
841 endif
843 ;***************************************************************
844 ;pascal void open_image(const char *name, struct image_himem *m);
845 ;***************************************************************
846 global @open_image$qpxzcp11image_himem:near
847 proc @open_image$qpxzcp11image_himem near
849 pop cx ;caller return address
850 pop ax ; m
851 pop bx ; name
852 push cx
853 push di
854 xchg ax,di
855 mov [(image_himem di).next_chunk],offset next_chunk
856 mov [(image_himem di).state],bx
857 push bx
858 @@next:
859 call [(image_himem di).next_chunk] ; m->next_chunk()
860 ifndef NO386
861 add eax,3
862 and al,0FCh
863 add [(image_himem di).size],eax ; m->size += m->chunk_size
864 or eax,eax
865 else
866 add ax,3
867 adc dx,0
868 and al,0FCh
869 add [word (image_himem di).size],ax ; m->size += m->chunk_size
870 adc [word ((image_himem di).size)+2],dx
871 or ax,dx
872 endif
873 jnz @@next
874 pop [(image_himem di).state]
875 call [(image_himem di).next_chunk] ; m->next_chunk()
876 pop di
877 ret
879 endp @open_image$qpxzcp11image_himem
882 ;***************************************************************
883 ;pascal int read_image(struct image_himem *m, char* data, int sz);
884 ;***************************************************************
885 global @read_image$qp11image_himempvi:near
886 proc @read_image$qp11image_himempvi near
888 arg sz :word, \
889 data :word, \
890 m :word = PARAM_SIZE
892 push bp
893 mov bp,sp
894 push si di
895 mov di,[m]
896 mov si,[data]
897 mov bp,[sz]
898 push bp ; original size
899 @@loop:
900 ifndef NO386
901 movzx ecx,bp
902 mov eax,[(image_himem di).chunk_size]
903 cmp ecx,eax
904 jb @@szok
905 else
906 mov cx,bp
907 mov ax,[word (image_himem di).chunk_size]
908 cmp cx,ax
909 jb @@szok
910 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
911 jne @@szok
912 endif
913 xchg ax,cx
914 @@szok:
915 jcxz image_done
916 mov dx,si
917 mov bx,[word di]
918 call @read$cxdxbx
919 jc image_done
920 add si,ax
921 xor cx,cx
922 ifndef NO386
923 cwde ; ax < 8000h
924 sub [(image_himem di).chunk_size],eax
925 else
926 cwd ; ax < 8000h
927 sub [word (image_himem di).chunk_size],ax
928 sbb [word ((image_himem di).chunk_size)+2],dx
929 jnz @@fill
930 cmp [word (image_himem di).chunk_size],dx
931 endif
932 jnz @@fill
933 inc cx
934 @@fill:
935 test al,3
936 je @@filled
937 mov [si],ch
938 inc si
939 inc ax
940 jmp @@fill
941 @@filled:
942 ifndef NO386
943 sub [(image_himem di).remaining],eax
944 else
945 sub [word (image_himem di).remaining],ax
946 sbb [word ((image_himem di).remaining)+2],dx
947 endif
948 sub bp,ax
949 pushf
950 jcxz @@same_chunk
951 call [(image_himem di).next_chunk]
952 @@same_chunk:
953 popf
954 jnz @@loop
955 image_done:
956 pop ax ; original size
957 sub ax,bp
958 pop di si bp
959 ret 6
961 endp @read_image$qp11image_himempvi
964 ;***************************************************************
965 ;pascal unsigned long strtol(const char *s);
966 ;***************************************************************
967 global @strtol$qpxzc:near
968 proc @strtol$qpxzc near
970 pop ax ;caller return address
971 pop cx ; s
972 push ax
973 ifndef NO386
974 xor ebx,ebx
975 push si
976 jcxz @@end
977 mov si,cx
978 xor ecx,ecx
979 xor eax,eax
980 lodsb
981 mov dx,ax
982 or al,20h
983 cmp al,'n' ; vga=normal
984 je @@vga
985 dec cx
986 cmp al,'e' ; vga=extended
987 je @@vga
988 dec cx
989 cmp al,'a' ; vga=ask
990 jne @@notvga
991 @@vga:
992 dec cx
993 xchg ax,cx
994 cwd
995 jmp @@popsiret
996 @@notvga:
997 mov cx,10 ; radix
998 xchg ax,dx
999 cmp al,'+'
1000 je @@radixskip
1001 cmp al,'-'
1002 clc
1003 jne @@radixkeep
1004 stc
1005 @@radixskip:
1006 lodsb
1007 @@radixkeep:
1008 pushf
1009 cmp al,'0'
1010 jne @@radixok
1011 mov cl,8
1012 lodsb
1013 or al,20h
1014 cmp al,'x'
1015 jne @@radixok
1016 mov cl,16
1017 @@strtollp:
1018 lodsb
1019 @@radixok:
1020 or al,20h
1021 sub al,'0'
1022 jb @@endstrtol
1023 cmp al,9
1024 jbe @@digitok
1025 cmp al,'a'-'0'
1026 jb @@endstrtol
1027 sub al,'a'-'0'-10
1028 @@digitok:
1029 cmp al,cl
1030 jae @@endstrtol
1031 xchg eax,ebx
1032 mul ecx
1033 add eax,ebx
1034 xchg eax,ebx
1035 jmp @@strtollp
1036 @@endstrtol:
1037 mov cl,10
1038 cmp al,'k'-'a'+10
1039 je @@shift
1040 mov cl,20
1041 cmp al,'m'-'a'+10
1042 je @@shift
1043 mov cl,30
1044 cmp al,'g'-'a'+10
1045 jne @@noshift
1046 @@shift:
1047 shl ebx,cl
1048 @@noshift:
1049 popf
1050 jnc @@end
1051 neg ebx
1052 @@end:
1053 push ebx
1054 pop ax
1055 pop dx
1056 @@popsiret:
1057 pop si
1058 else
1059 push si
1060 push di
1061 xor ax,ax
1062 cwd
1063 jcxz @@goend
1064 xchg ax,di
1065 mov si,cx
1066 lodsb
1067 mov bx,ax
1068 or al,20h
1069 mov cx,-1
1070 cmp al,'n' ; vga=normal
1071 je @@vga
1072 dec cx
1073 cmp al,'e' ; vga=extended
1074 je @@vga
1075 dec cx
1076 cmp al,'a' ; vga=ask
1077 jne @@notvga
1078 @@vga:
1079 xchg ax,cx
1080 @@goend:
1081 jmp @@popdisiret
1082 @@notvga:
1083 mov cx,10 ; radix
1084 xchg ax,bx
1085 cmp al,'+'
1086 je @@radixskip
1087 cmp al,'-'
1088 clc
1089 jne @@radixkeep
1090 stc
1091 @@radixskip:
1092 lodsb
1093 @@radixkeep:
1094 pushf
1095 cmp al,'0'
1096 jne @@radixok
1097 mov cl,8
1098 lodsb
1099 or al,20h
1100 cmp al,'x'
1101 jne @@radixok
1102 mov cl,16
1103 @@strtollp:
1104 lodsb
1105 @@radixok:
1106 or al,20h
1107 sub al,'0'
1108 jb @@endstrtol
1109 cmp al,9
1110 jbe @@digitok
1111 cmp al,'a'-'0'
1112 jb @@endstrtol
1113 sub al,'a'-'0'-10
1114 @@digitok:
1115 cmp al,cl
1116 jae @@endstrtol
1118 push ax
1119 push si
1120 push dx
1121 xchg ax,di
1122 mul cx
1123 xchg ax,di
1124 xchg ax,dx
1125 xchg ax,si
1126 pop ax
1127 mul cx
1128 add ax,si
1129 pop si
1130 xchg ax,dx
1131 pop ax
1132 mov ah,0
1133 add di,ax
1134 adc dx,0
1136 jmp @@strtollp
1137 @@endstrtol:
1138 mov cl,10
1139 cmp al,'k'-'a'+10
1140 je @@shift
1141 mov cl,20
1142 cmp al,'m'-'a'+10
1143 je @@shift
1144 mov cl,30
1145 cmp al,'g'-'a'+10
1146 jne @@noshift
1147 @@shift:
1148 rcl di,1
1149 shl dx,1
1150 loop @@shift
1151 @@noshift:
1152 popf
1153 jnc @@end
1154 not dx
1155 neg di
1156 jne @@end
1157 inc dx
1158 @@end:
1159 xchg ax,di
1160 @@popdisiret:
1161 pop di
1162 pop si
1163 endif
1164 strtol_ret:
1165 ret
1167 endp @strtol$qpxzc
1170 ifdef NO386
1171 ;***************************************************************
1172 ;u16 topseg();
1173 ;***************************************************************
1174 global _topseg:near
1175 proc _topseg near
1177 int 12h
1178 jnc @@max640k
1179 mov ax,640 ; 9000
1180 @@max640k:
1181 dec ax
1182 and al,0C0h
1183 mov cl,6
1184 shl ax,cl
1185 ret
1187 endp _topseg
1188 endif
1190 ifdef EXTRA
1191 p8086
1192 ;***************************************************************
1193 ;char *progname(void)
1194 ;***************************************************************
1195 global _progname:near
1196 proc _progname near
1198 push si di es
1199 mov ah,30h
1200 int 21h
1201 xor di,di
1202 cmp al,3
1203 mov ax,di
1204 jb @@skip
1205 ;mov es,[cs:2Ch]
1206 mov es,[di+2Ch]
1207 mov cx,sp ; big enough
1208 @@loop:
1209 repne
1210 scasb
1211 scasb
1212 jne @@loop
1213 inc di
1214 inc di
1215 mov si,di ; progname @es:di
1216 repne
1217 scasb
1218 mov cx,di
1219 sub cx,si ; progname len
1220 call malloc_or_die ; keep cx
1221 mov di,ax
1222 push ds
1223 push es
1224 pop ds
1225 pop es
1226 rep
1227 movsb
1228 push es
1229 pop ds
1230 @@skip:
1231 pop es di si
1232 ret
1234 endp _progname
1237 ;***************************************************************
1238 ;pascal void chdirname(char *path)
1239 ;***************************************************************
1240 global @chdirname$qpzc:near
1241 proc @chdirname$qpzc near
1243 pop ax
1244 pop bx
1245 push ax
1247 cmp [byte bx+1],3Ah ; ':'
1248 jne @@nodisk
1249 mov dl,20h
1250 or dl,[bx]
1251 sub dl,61h
1252 mov ah,0Eh
1253 int 21h
1254 inc bx
1255 inc bx
1256 @@nodisk:
1257 xor cx,cx
1258 @@next:
1259 mov al,[bx]
1260 cmp al,5Ch
1261 jne @@tsteos
1262 mov dx,bx
1263 inc cx
1264 @@tsteos:
1265 inc bx
1266 or al,al
1267 jnz @@next
1268 jcxz @@end
1269 mov bx,dx
1270 push [word bx]
1271 mov [bx],al
1272 stc
1273 mov ax,713Bh ; chdir long filename (ds:dx)
1274 int 21h
1275 mov ah,3Bh ; chdir(ds:dx)
1276 jnc @@chdirdone
1277 int 21h
1278 @@chdirdone:
1279 pop [word bx]
1280 @@end:
1281 ret
1283 endp @chdirname$qpzc
1286 ;***************************************************************
1287 ;pascal char *ultoa(unsigned long n);
1288 ;***************************************************************
1289 global @ultoa$qul:near
1290 proc @ultoa$qul near
1292 pop dx
1293 pop cx
1294 pop ax
1295 push dx ; AX:CX = n
1296 push si
1297 mov si,10
1298 mov bx,offset ultoabuf+11
1299 @@loop:
1300 dec bx
1301 xor dx,dx
1302 div si ; DX:AX = 0000:hi(n)
1303 xchg ax,cx ; CX = hi(n)/10
1304 div si ; DX:AX = hi(n)%10:lo(n)
1305 xchg ax,cx ; CX = lo(n/10)
1306 ; AX = hi(n)/10 = hi(n/10)
1307 mov [byte bx],'0'
1308 add [bx],dl ; DL = n%10
1309 mov dx,ax
1310 or dx,cx
1311 jnz @@loop
1312 xchg ax,bx
1313 pop si
1314 ret
1316 endp @ultoa$qul
1319 ;***************************************************************
1320 ;pascal unsigned long kver2ul(char *kernel_version);
1321 ;***************************************************************
1322 global @kver2ul$qpzc:near
1323 proc @kver2ul$qpzc near
1325 pop bx
1326 pop ax
1327 push bx
1328 push si
1329 xchg ax,si
1330 xor bx,bx
1331 mov cx,304h
1332 @@number:
1333 xor ax,ax
1334 cwd
1335 @@digit:
1336 shl al,cl
1337 shl ax,cl
1338 lodsb
1339 sub al,30h
1340 cmp al,9
1341 jbe @@digit
1342 mov dl,bh
1343 mov bh,bl
1344 mov bl,ah
1345 dec ch
1346 jnz @@number
1347 xchg ax,bx
1348 pop si
1349 kver2ulret:
1350 ret
1352 endp @kver2ul$qpzc
1354 endif
1356 ;***************************************************************
1357 ;void try_default_args();
1358 ;pascal void set_cmdline(const char *filename);
1359 ;***************************************************************
1360 ifdef EXTRA
1362 global _try_default_args:near
1363 proc _try_default_args near
1365 mov bx,offset tazboot_cmd
1366 call open
1367 jc kver2ulret
1368 mov cx,4096
1369 mov di,[_heap_top]
1370 extrn read_cmdline:near
1371 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1373 endp _try_default_args
1375 endif
1377 ends _TEXT
1379 end
1381 ;###### END OF FILE ############################################