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

linld/tazboot: can boot memtest & ipxe
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 05 13:22:08 2017 +0100 (2017-03-05)
parents 76087975885f
children 008ac2992c52
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:word
20 extrn _bss_end
21 _heap_top dw _bss_end
22 msg_hang db "High mem corrupted - not exiting to DOS"
23 msg_crlf db 13,10,0
24 vcpi_alloc_err db "vcpi "
25 msg_malloc db "malloc failure",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 ;char* strcpy(const char* a, const char* b);
51 ;char* strcat(const char* a, const char* b);
52 ;char* strcatb(const char* a, const char* b);
53 ;***************************************************************
54 global _strcpy:near
55 proc _strcpy near
57 mov dl,0
58 db 0bbh ; mov bx,imm opcode
59 global _strcat:near
60 _strcat:
61 mov dl,1
62 db 0bbh ; mov bx,imm opcode
63 global _strcatb:near
64 _strcatb:
65 mov dl,3
66 pop ax ;caller return address
67 pop cx ; a
68 pop bx ; b
69 push bx
70 push cx
71 push ax
72 push si
73 mov si,cx
74 shr dl,1
75 jnc @@nocat
76 @@catlp:
77 lodsb
78 cmp al,0
79 jne @@catlp
80 dec si
81 shr dl,1
82 jnc @@nocat
83 cmp cx,si
84 jz @@nocat
85 mov [word si],20h
86 inc si
87 @@nocat:
88 sub bx,si
89 @@cpylp:
90 mov al,[bx+si]
91 mov [si],al
92 inc si
93 cmp al,0
94 jne @@cpylp
95 mov ax,cx
96 pop si
97 ret
99 endp _strcpy
102 ;***************************************************************
103 ;void* malloc(unsigned sz);
104 ;***************************************************************
105 global _malloc:near
106 proc _malloc near
108 pop ax ;caller return address
109 pop cx ; sz
110 push cx
111 push ax
112 global malloc:near ; malloc(cx)
113 malloc: ; keep CX, use AX,BX
114 mov ax,[_heap_top]
115 mov bx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
116 add bx,sp
117 sub bx,ax ; can't overflow
118 cmp bx,cx
119 mov bx,offset msg_malloc
120 jb puts
121 add [_heap_top],cx ; _BEG has zero'd heap
122 ;mov bx,ax
123 @@zalloc:
124 ;mov [byte bx],0
125 ;inc bx ; ZF=0
126 ;loop @@zalloc
127 ret
129 endp _malloc
132 ;***************************************************************
133 ;void puts(const char* s):
134 ;***************************************************************
135 global _puts:near
136 proc _puts near
138 pop ax ;caller return address
139 pop bx ; s
140 push bx
141 push ax
142 global puts:near ; puts(bx)
143 puts:
144 call putsz
145 mov bx,offset msg_crlf
147 global putsz:near ; putsz(bx)
148 putsz:
149 push bx
150 call strlen
151 pop dx
152 xchg ax,cx
153 mov bx,1
154 mov ah,40h
155 int 21h
156 xor ax,ax ; ZF=1 (for malloc failure)
157 ret
159 endp _puts
162 ;***************************************************************
163 ;int fileattr(const char* name);
164 ;***************************************************************
165 global _fileattr:near
166 proc _fileattr near
168 pop ax ;caller return address
169 pop dx ; name
170 push dx
171 push ax
172 mov ax,4300h
173 int 21h
174 xchg ax,cx
175 jmp chkc
177 endp _fileattr
180 ;***************************************************************
181 ;int open(const char* name, int flags=O_RDONLY);
182 ;***************************************************************
183 global _open:near
184 proc _open near
186 pop ax ;caller return address
187 pop bx ; name
188 push bx
189 push ax
190 global open:near ; open(bx)
191 open:
192 mov dx,bx
193 mov ax,3d00h
194 dos:
195 int 21h
196 chkc:
197 jnc doret
198 fail:
199 sbb ax,ax ; ax=-1 CF
200 cwd
201 doret:
202 ifndef NO386
203 push dx ; see next_chunk:lseek
204 push ax
205 pop eax
206 endif
207 ret
209 endp _open
212 ;***************************************************************
213 ;int close(int fd);
214 ;***************************************************************
215 global _close:near
216 proc _close near
218 pop ax ;caller return address
219 pop bx ; fd
220 push bx
221 push ax
222 global close:near ; close(bx)
223 close:
224 mov ah,3Eh
225 or bx,bx
226 jnz dos
227 ret
229 endp _close
232 ;***************************************************************
233 ;int read(int fd, void* data, int sz);
234 ;int write(int fd, const void* data, int sz);
235 ;***************************************************************
236 global _read:near
237 proc _read near
239 stc
240 db 0B0h ; mov al,im
241 global _write:near
242 clc
243 pop ax ;caller return address
244 pop bx ; fd
245 pop dx ; data
246 pop cx ; sz
247 push cx
248 push dx
249 push bx
250 push ax
251 mov ah,40h
252 sbb ah,0
253 jcxz fail
254 jmp dos
256 endp _read
258 ifdef EXTRA
259 ;***************************************************************
260 ;long lseekset(int fd, unsigned long sz);
261 ;***************************************************************
262 global _lseekset:near
263 proc _lseekset near
265 pop ax ;caller return address
266 pop bx ; fd
267 pop dx ; sz lo
268 pop cx ; sz hi
269 push cx
270 push dx
272 else
273 ;***************************************************************
274 ;long seekset(int fd, unsigned sz);
275 ;***************************************************************
276 global _seekset:near
277 proc _seekset near
279 xor cx,cx
280 pop ax ;caller return address
281 pop bx ; fd
282 pop dx ; sz
283 push dx
284 endif
286 push bx
287 push ax
288 global lseekset:near
289 lseekset:
290 clc
291 db 0B0h ; mov al,im
292 global rewind:near
293 rewind: ; rewind(bx)
294 stc
295 mov ax,4200h
296 jnc dos
297 lseek0: ; lseek0(bx,ax=dir)
298 cwd
299 xor cx,cx
300 jmp dos
302 ifdef EXTRA
303 endp _lseekset
304 else
305 endp _seekset
306 endif
308 ifdef EXTRA
309 struc isostate ; struct isostate {
310 fd dw ? ; 0 int fd;
311 fileofs dd ? ; 2 unsigned long fileofs;
312 filesize dd ? ; 6 unsigned long filesize;
313 filemod dw ? ;10 unsigned short filemod;
314 filename dw ? ;12 char *filename;
315 dirofs dd ? ;14 unsigned long dirofs;
316 dirsize dd ? ;16 unsigned long dirsize;
317 curdirofs dd ? ;20 unsigned long curdirofs;
318 curdirsize dd ? ;24 unsigned long curdirsize;
319 curpos dd ? ;28 unsigned long curpos;
320 ends ; } isostate;
321 ;***************************************************************
322 ;unsigned long isolseek(const unsigned long *offset);
323 ;***************************************************************
324 global _isolseek:near
325 proc _isolseek near
327 pop ax
328 pop bx
329 push bx
330 push ax
331 mov dx,[bx]
332 mov cx,[bx+2]
333 extrn _isostate:isostate
334 mov bx,[_isostate.fd]
335 jmp lseekset ; (bx=fd, sz=cx:dx)
337 endp _isolseek
338 endif
341 ;***************************************************************
342 ;int strlen(const char* s);
343 ;***************************************************************
344 global _strlen:near
345 proc _strlen near
347 pop ax ;caller return address
348 pop bx ; s
349 push bx
350 push ax
351 global strlen:near ; strlen(bx)
352 strlen:
353 mov cx,bx
354 jcxz @@end
355 dec bx
356 @@lenlp:
357 inc bx
358 cmp [byte bx],0
359 jne @@lenlp
360 sub bx,cx
361 @@end:
362 xchg ax,bx
363 ret
365 endp _strlen
368 ;***************************************************************
369 ;int strhead(const char* a,const char* b);
370 ;***************************************************************
371 global _strhead:near
372 proc _strhead near
374 pop cx ;caller return address
375 pop bx ; a
376 pop ax ; b
377 push ax
378 push bx
379 push cx
380 @@loop:
381 xchg ax,bx
382 mov cl,[bx] ; cl = *b++
383 inc bx
384 or cl,cl ; clear C
385 jz fail ; return 0
386 xchg ax,bx
387 xor cl,[bx] ; cl -= *a++
388 inc bx
389 and cl,0dfh ; case insensitive
390 jz @@loop
391 ret ; return b (is not 0)
393 endp _strhead
396 ;***************************************************************
397 ;char* malloc_or_die(unsigned size);
398 ;***************************************************************
399 global _malloc_or_die:near
400 proc _malloc_or_die near
402 pop ax ;caller return address
403 pop cx ; size
404 push cx
405 push ax
406 global malloc_or_die:near ; malloc_or_die(cx)
407 malloc_or_die:
408 call malloc
409 jz _exit
410 ret
412 endp _malloc_or_die
415 ;***************************************************************
416 ;int die(const char* msg);
417 ;int exit();
418 ;int abort();
419 ;***************************************************************
420 global _die:near
421 proc _die near
423 pop ax ;caller return address
424 pop bx ; s
425 push bx
426 push ax
427 global die:near ; die(bx)
428 die:
429 call puts
430 global _exit:near
431 _exit:
432 mov al,[_no_exit]
433 cmp al,0
434 jne @@hang
435 extrn exit:near
436 inc ax
437 jmp near exit
438 @@hang:
439 mov bx, offset msg_hang
440 call puts
441 global _abort:near
442 _abort:
443 cli
444 @@stop:
445 hlt
446 jmp @@stop
448 endp _die
450 struc image_himem ;struct image_himem {
451 fd dw ? ; 0 int fd;
452 fallback dd ? ; 2 u32 fallback;
453 size dd ? ; 6 u32 size;
454 remaining dd ? ;10 u32 remaining;
455 buf dd ? ;14 u32 buf;
456 bufv dw ? ;18 u32 *bufv;
457 errmsg dw ? ;20 char *errmsg;
458 chunk_size dd ? ;22 u32 chunk_size;
459 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
460 state dw ? ;28 u16 state;
461 fd2close dw ? ;30 u16 fd2close;
462 ends ;};
464 ;***************************************************************
465 ;void next_chunk(struct image_himem *di);
466 ;***************************************************************
467 proc next_chunk near
469 push si
470 mov bx,[(image_himem di).fd]
471 call close
472 ifndef NO386
473 xor eax,eax
474 else
475 xor ax,ax
476 endif
477 cwd
478 mov [(image_himem di).fd],ax
479 mov bx,[(image_himem di).state]
480 cmp al,[bx] ; ""
481 jz @@end
482 mov si,bx
483 @@scan:
484 lodsb
485 mov cx,si
486 cmp al,','
487 jz @@eos
488 cmp al,0
489 jnz @@scan
490 dec cx
491 @@eos:
492 mov [(image_himem di).state],cx
493 dec si
494 push [word si]
495 mov [byte si],dl ; set temp eos
496 call open
497 pop [word si] ; restore string
498 jc @@die
499 mov [(image_himem di).fd],ax
500 mov [(image_himem di).fd2close],ax
501 xchg ax,bx
502 mov ax,4202h ; SEEK_END
503 call lseek0
504 @@die:
505 mov bx,[(image_himem di).errmsg]
506 jc die
507 mov bx,[(image_himem di).fd]
508 ifndef NO386
509 push eax
510 call rewind
511 pop eax
512 @@end:
513 mov [(image_himem di).chunk_size],eax
514 else
515 push ax
516 push dx
517 call rewind
518 pop dx
519 pop ax
520 @@end:
521 mov [word (image_himem di).chunk_size],ax
522 mov [word ((image_himem di).chunk_size)+2],dx
523 endif
524 pop si
525 ret
527 endp next_chunk
530 ifdef LARGE_IMAGES
531 struc data_himem ;struct data_himem {
532 first dd ? ; 0 u32 first;
533 cacheidx dw ? ; 4 int cacheidx;
534 pageidx dw ? ; 6 int pageidx;
535 cache dd 1024 dup(?) ; 8 int cache;
536 page dd 1024 dup(?) ;4104 int page;
537 ends ;}; // size=8200
538 endif
540 ;***************************************************************
541 ;u32* malloc_bufv_or_die(struct image_himem *m);
542 ;***************************************************************
543 global _malloc_bufv_or_die:near
544 proc _malloc_bufv_or_die near
546 p386
547 pop bx ;caller return address
548 pop ax
549 push ax
550 push bx
551 push si
552 xchg ax,si
553 ifdef LARGE_IMAGES
554 mov cx,[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 ecx,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 _pm
597 mov bx,offset _pm+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 _initrd
608 mov bx,offset _initrd+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
664 ;***************************************************************
665 ; void memcpy_image(struct image_himem *m);
666 ;***************************************************************
667 global _memcpy_image:near
668 proc _memcpy_image near
670 pop ax ;caller return address
671 pop bx
672 push bx
673 push ax
674 ifndef NO386
675 mov edx,[(image_himem bx).fallback]
676 mov eax,[(image_himem bx).buf]
677 cmp eax,edx ; if (m->fallback != m->buf)
678 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
679 ifdef LARGE_IMAGES
680 mov ecx,[(image_himem bx).size]
681 memcpy_imagez:
682 push ecx
683 else
684 push [(image_himem bx).size]
685 endif
686 push eax
687 push 0
688 call_memcpy32:
689 push edx
690 else
691 mov ax,[word ((image_himem bx).fallback)]
692 mov dx,[word ((image_himem bx).fallback)+2]
693 mov cx,[word ((image_himem bx).buf)]
694 cmp ax,cx ; if (m->fallback != m->buf)
695 jnz @@do
696 cmp dx,[word ((image_himem bx).buf)+2]
697 jz @@skip ; memcpy32(m->fallback,0,m->buf,m->size)
698 @@do:
699 push [word ((image_himem bx).size)+2]
700 push [word ((image_himem bx).size)]
701 push [word ((image_himem bx).buf)+2]
702 push cx
703 xor cx,cx
704 push cx
705 call_memcpy32:
706 push dx
707 push ax
708 ifdef LARGE_IMAGES
709 jmp @@memcpy
710 memcpy_imagez:
711 p386
712 push ecx
713 push eax
714 push 0
715 push edx
716 ifdef NO386
717 p8086
718 endif
719 endif
720 endif
721 @@memcpy:
722 extrn _memcpy32:near
723 call near _memcpy32
724 add sp,14
725 @@skip:
726 ret
728 endp _memcpy_image
730 ;***************************************************************
731 ;void storepage(u32 *dst, u16 src);
732 ;***************************************************************
733 global _storepage:near
734 proc _storepage near
736 pop ax ;caller return address
737 pop bx
738 pop cx
739 push cx
740 push bx
741 push ax
742 ifndef NO386
743 mov edx,[bx]
744 else
745 mov ax,[bx]
746 mov dx,[bx+2]
747 endif
748 storepage:
749 ifndef NO386
750 push 0
751 push 4096
752 push 0
753 else
754 xor bx,bx
755 push bx
756 mov bh,4096/256
757 push bx
758 xor bx,bx
759 push bx
760 endif
761 push cx
762 push ds
763 jmp call_memcpy32
765 endp _storepage
768 ifdef LARGE_IMAGES
769 p386
770 ;***************************************************************
771 ;void reset_bufv(u32 *p);
772 ;***************************************************************
773 global _reset_bufv:near
774 proc _reset_bufv near
776 pop ax ;caller return address
777 pop bx
778 push bx
779 push ax
780 mov [curdata],bx
781 and [dword (data_himem bx).cacheidx],0
782 ret
784 endp _reset_bufv
786 ;***************************************************************
787 ;u32* prev_bufv();
788 ;u32* prev_bufv();
789 ;***************************************************************
790 global _prev_bufv:near
791 global _next_bufv:near
792 proc _prev_bufv near
794 stc
795 db 73h ; jnc
796 _next_bufv:
797 clc
798 sbb ax,ax
799 stc
800 rcl ax,1 ; -1/+1
801 xor ecx,ecx
802 push si
803 mov si,[curdata]
804 add ax,[(data_himem si).cacheidx]
805 test ax,0fc00h
806 jz @@gotpage
807 push ax ; FFFF / 0400
808 sar ax,8 ; FFFC / 0004
809 and al,0fch
810 add [(data_himem si).pageidx],ax
811 mov bx,[(data_himem si).pageidx]
812 lea bx,[(data_himem bx+si).page]
813 mov edx,ds
814 shl edx,4
815 lea cx,[(data_himem si).cache]
816 add edx,ecx
817 mov eax,[bx]
818 or eax,eax
819 jnz @@pageok
820 pop ax
821 xchg ax,bx
822 pop si
823 ret
824 @@pageok:
825 mov cx,4096
826 call memcpy_imagez ; get page
827 pop ax ; FFFF / 0400
828 cbw
829 shr ax,6 ; 03FF / 0000
830 @@gotpage:
831 mov [(data_himem si).cacheidx],ax
832 shl ax,2
833 xchg ax,bx
834 lea ax,[(data_himem bx+si).cache]
835 or bx,[(data_himem si).pageidx] ; !pageidx && !cacheidx
836 jnz @@notfirst2
837 xchg ax,si ; &first
838 @@notfirst2:
839 pop si
840 ret
841 ifdef NO386
842 p8086
843 endif
845 endp _prev_bufv
846 endif
849 ;***************************************************************
850 ;void open_image(const char *name, struct image_himem *m);
851 ;***************************************************************
852 global _open_image:near
853 proc _open_image near
855 arg fname :word, \
856 m :word = PARAM_SIZE
858 push bp
859 mov bp,sp
860 push si di
861 ifndef NO386
862 xor eax,eax ; 1st loop flag + eos
863 else
864 xor ax,ax ; 1st loop flag + eos
865 endif
866 mov di,[m]
867 cmp [(image_himem di).fd],ax
868 jnz @@alreadydone
869 ifndef NO386
870 mov [(image_himem di).size],eax ; m->size = 0L
871 else
872 mov [word (image_himem di).size],ax ; m->size = 0L
873 mov [word ((image_himem di).size)+2],ax
874 endif
875 mov [(image_himem di).next_chunk],offset next_chunk
876 mov si,[fname]
877 mov [(image_himem di).state],si
878 @@next:
879 push di
880 call [(image_himem di).next_chunk] ; m->next_chunk()
881 pop di
882 ifndef NO386
883 add eax,3
884 and al,0FCh
885 add [(image_himem di).size],eax ; m->size += m->chunk_size
886 or eax,eax
887 jnz @@next
888 else
889 mov cx,ax
890 or cx,dx
891 add ax,3
892 adc dx,0
893 and al,0FCh
894 add [word (image_himem di).size],ax ; m->size += m->chunk_size
895 adc [word ((image_himem di).size)+2],dx
896 inc cx ; jcxnz
897 loop @@next
898 endif
899 mov [(image_himem di).state],si
900 push di
901 call [(image_himem di).next_chunk] ; m->next_chunk()
902 pop di
903 @@alreadydone:
904 push ax
905 image_done:
906 pop ax
907 pop di si bp
908 ret
910 endp _open_image
913 ;***************************************************************
914 ;int read_image(struct image_himem *m, void* data, int sz);
915 ;***************************************************************
916 global _read_image:near
917 proc _read_image near
919 arg m :word, \
920 data :word, \
921 sz :word = PARAM_SIZE
923 push bp
924 mov bp,sp
925 push si di
926 ifndef NO386
927 push 0 ; return value
928 else
929 xor ax,ax
930 push ax
931 endif
932 mov di,[m]
933 @@loop:
934 ifndef NO386
935 xor ecx,ecx
936 mov cx,[word sz]
937 @@chksz:
938 mov eax,[(image_himem di).chunk_size]
939 cmp ecx,eax
940 jb @@szok
941 xchg eax,ecx
942 else
943 mov cx,[word sz]
944 @@chksz:
945 mov ax,[word (image_himem di).chunk_size]
946 cmp cx,ax
947 jb @@szok
948 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
949 jne @@szok
950 xchg ax,cx
951 endif
952 @@szok:
953 jcxz image_done
954 push cx
955 push [word data]
956 push [word di]
957 call _read
958 pop dx
959 pop bx
960 pop dx
961 jc image_done
962 add bx,ax
963 xor cx,cx
964 ifndef NO386
965 cwde ; ax < 8000h
966 sub [(image_himem di).chunk_size],eax
967 else
968 cwd ; ax < 8000h
969 sub [word (image_himem di).chunk_size],ax
970 sbb [word ((image_himem di).chunk_size)+2],dx
971 jnz @@fill
972 cmp [word (image_himem di).chunk_size],dx
973 endif
974 jnz @@fill
975 dec cx
976 @@fill:
977 test al,3
978 je @@filled
979 mov [bx],dl
980 inc bx
981 inc ax
982 jmp @@fill
983 @@filled:
984 ifndef NO386
985 sub [(image_himem di).remaining],eax
986 else
987 sub [word (image_himem di).remaining],ax
988 sbb [word ((image_himem di).remaining)+2],dx
989 endif
990 add [bp-4-2],ax
991 add [word data],ax
992 sub [word sz],ax
993 pushf
994 and cx,[(image_himem di).next_chunk]
995 jz @@same_chunk
996 push di
997 call cx ; m->next_chunk()
998 pop di
999 @@same_chunk:
1000 popf
1001 jnz @@loop
1002 jmp image_done
1004 endp _read_image
1007 ;***************************************************************
1008 ;unsigned long strtol(const char *s);
1009 ;***************************************************************
1010 global _strtol:near
1011 proc _strtol near
1013 ifndef NO386
1014 pop ax ;caller return address
1015 pop cx ; s
1016 push cx
1017 push ax
1018 xor ebx,ebx
1019 push si
1020 jcxz @@end
1021 mov si,cx
1022 xor ecx,ecx
1023 xor eax,eax
1024 lodsb
1025 mov dx,ax
1026 or al,20h
1027 cmp al,'n' ; vga=normal
1028 je @@vga
1029 dec cx
1030 cmp al,'e' ; vga=extended
1031 je @@vga
1032 dec cx
1033 cmp al,'a' ; vga=ask
1034 jne @@notvga
1035 @@vga:
1036 dec cx
1037 xchg ax,cx
1038 cwd
1039 jmp @@popsiret
1040 @@notvga:
1041 mov cx,10 ; radix
1042 xchg ax,dx
1043 cmp al,'+'
1044 je @@radixskip
1045 cmp al,'-'
1046 clc
1047 jne @@radixkeep
1048 stc
1049 @@radixskip:
1050 lodsb
1051 @@radixkeep:
1052 pushf
1053 cmp al,'0'
1054 jne @@radixok
1055 mov cl,8
1056 lodsb
1057 or al,20h
1058 cmp al,'x'
1059 jne @@radixok
1060 mov cl,16
1061 @@strtollp:
1062 lodsb
1063 @@radixok:
1064 or al,20h
1065 sub al,'0'
1066 jb @@endstrtol
1067 cmp al,9
1068 jbe @@digitok
1069 cmp al,'a'-'0'
1070 jb @@endstrtol
1071 sub al,'a'-'0'-10
1072 @@digitok:
1073 cmp al,cl
1074 jae @@endstrtol
1075 xchg eax,ebx
1076 mul ecx
1077 add eax,ebx
1078 xchg eax,ebx
1079 jmp @@strtollp
1080 @@endstrtol:
1081 mov cl,10
1082 cmp al,'k'-'a'+10
1083 je @@shift
1084 mov cl,20
1085 cmp al,'m'-'a'+10
1086 je @@shift
1087 mov cl,30
1088 cmp al,'g'-'a'+10
1089 jne @@noshift
1090 @@shift:
1091 shl ebx,cl
1092 @@noshift:
1093 popf
1094 jnc @@end
1095 neg ebx
1096 @@end:
1097 push ebx
1098 pop ax
1099 pop dx
1100 @@popsiret:
1101 pop si
1102 else
1103 pop ax ;caller return address
1104 pop cx ; s
1105 push cx
1106 push ax
1107 push si
1108 push di
1109 xor ax,ax
1110 cwd
1111 jcxz @@goend
1112 xchg ax,di
1113 mov si,cx
1114 lodsb
1115 mov bx,ax
1116 or al,20h
1117 mov cx,-1
1118 cmp al,'n' ; vga=normal
1119 je @@vga
1120 dec cx
1121 cmp al,'e' ; vga=extended
1122 je @@vga
1123 dec cx
1124 cmp al,'a' ; vga=ask
1125 jne @@notvga
1126 @@vga:
1127 xchg ax,cx
1128 @@goend:
1129 jmp @@popdisiret
1130 @@notvga:
1131 mov cx,10 ; radix
1132 xchg ax,bx
1133 cmp al,'+'
1134 je @@radixskip
1135 cmp al,'-'
1136 clc
1137 jne @@radixkeep
1138 stc
1139 @@radixskip:
1140 lodsb
1141 @@radixkeep:
1142 pushf
1143 cmp al,'0'
1144 jne @@radixok
1145 mov cl,8
1146 lodsb
1147 mov al,20h
1148 cmp al,'x'
1149 jne @@radixok
1150 mov cl,16
1151 @@strtollp:
1152 lodsb
1153 @@radixok:
1154 or al,20h
1155 sub al,'0'
1156 jb @@endstrtol
1157 cmp al,9
1158 jbe @@digitok
1159 cmp al,'a'-'0'
1160 jb @@endstrtol
1161 sub al,'a'-'0'-10
1162 @@digitok:
1163 cmp al,cl
1164 jae @@endstrtol
1166 push ax
1167 push si
1168 push dx
1169 xchg ax,di
1170 mul cx
1171 xchg ax,di
1172 xchg ax,dx
1173 xchg ax,si
1174 pop ax
1175 mul cx
1176 add ax,si
1177 pop si
1178 xchg ax,dx
1179 pop ax
1180 mov ah,0
1181 add di,ax
1182 adc dx,0
1184 jmp @@strtollp
1185 @@endstrtol:
1186 mov cl,10
1187 cmp al,'k'-'a'+10
1188 je @@shift
1189 mov cl,20
1190 cmp al,'m'-'a'+10
1191 je @@shift
1192 mov cl,30
1193 cmp al,'g'-'a'+10
1194 jne @@noshift
1195 @@shift:
1196 rcl di,1
1197 shl dx,1
1198 loop @@shift
1199 @@noshift:
1200 popf
1201 jnc @@end
1202 not dx
1203 neg di
1204 jne @@end
1205 inc dx
1206 @@end:
1207 xchg ax,di
1208 @@popdisiret:
1209 pop di
1210 pop si
1211 endif
1212 ret
1214 endp _strtol
1217 ifdef NO386
1218 ;***************************************************************
1219 ;u16 topseg();
1220 ;***************************************************************
1221 global _topseg:near
1222 proc _topseg near
1224 int 12h
1225 jnc @@max640k
1226 mov ax,640 ; 9000
1227 @@max640k:
1228 dec ax
1229 and al,0C0h
1230 mov cl,6
1231 shl ax,cl
1232 ret
1234 endp _topseg
1235 endif
1237 ifdef EXTRA
1238 p8086
1240 ;***************************************************************
1241 ;int strcmp(const char* a,const char* b);
1242 ;***************************************************************
1243 global _strcmp:near
1244 proc _strcmp near
1246 pop cx ;caller return address
1247 pop bx ; a
1248 pop ax ; b
1249 push ax
1250 push bx
1251 push cx
1252 push si
1253 xchg ax,si
1254 sub bx,si
1255 @@lp:
1256 mov al,[si]
1257 sub al,[bx+si]
1258 jnz @@out
1259 lodsb
1260 cmp al,0
1261 jne @@lp
1262 @@out:
1263 cbw
1264 pop si
1265 ret
1267 endp _strcmp
1270 ;***************************************************************
1271 ;char strstr(const char* a,const char* b);
1272 ;***************************************************************
1273 global _strstr:near
1274 proc _strstr near
1276 pop ax ;caller return address
1277 pop cx ; a
1278 pop dx ; b
1279 push dx
1280 push cx
1281 push ax
1282 push si
1283 @@loop:
1284 xor ax,ax
1285 mov si,cx
1286 cmp [si],al ; *a
1287 jz @@end ; return ax = NULL
1288 mov bx,dx
1289 sub bx,si
1290 @@match:
1291 or ah,[bx+si] ; *b
1292 jz @@found
1293 lodsb
1294 sub ah,al
1295 jz @@match
1296 inc cx
1297 jmp @@loop
1298 @@found:
1299 xchg ax,cx
1300 @@end:
1301 pop si
1302 ret
1304 endp _strstr
1307 ;***************************************************************
1308 ;char *progname(void)
1309 ;***************************************************************
1310 global _progname:near
1311 proc _progname near
1313 push si di es
1314 mov ah,30h
1315 int 21h
1316 cmp al,3
1317 jb @@skip
1318 xor di,di
1319 mov es,[cs:2Ch]
1320 mov cx,-1
1321 mov ax,di
1322 @@loop1:
1323 repne
1324 scasb
1325 scasb
1326 jne @@loop1
1327 lea si,[di+2]
1328 mov bx, si
1329 call strlen
1330 xchg ax,cx
1331 inc cx
1332 call malloc_or_die
1333 xchg ax,di
1334 push ds
1335 push ds
1336 push es
1337 pop ds
1338 pop es
1339 push di
1340 @@loop2:
1341 lodsb
1342 stosb
1343 or al,al
1344 jnz @@loop2
1345 pop ax
1346 pop ds
1347 @@skip:
1348 pop es di si
1349 ret
1351 endp _progname
1354 ;***************************************************************
1355 ;int chdir(char *path);
1356 ;***************************************************************
1357 global _chdir:near
1358 proc _chdir near
1360 pop ax
1361 pop dx
1362 push dx
1363 push ax
1364 chdir:
1365 stc
1366 mov ax,713Bh
1367 int 21h
1368 jnc @@end
1369 mov ah,3Bh
1370 int 21h
1371 @@end:
1372 sbb ax,ax
1373 ret
1375 endp _chdir
1378 ;***************************************************************
1379 ;int chdirname(char *path)
1380 ;***************************************************************
1381 global _chdirname:near
1382 proc _chdirname near
1384 pop ax
1385 pop bx
1386 push bx
1387 push ax
1389 cmp [byte bx+1],3Ah
1390 jne @@nodisk
1391 mov dl,[bx]
1392 or dl,20h
1393 sub dl,61h
1394 mov ah,0Eh
1395 push bx
1396 int 21h
1397 pop bx
1398 inc bx
1399 inc bx
1400 @@nodisk:
1401 mov dx,bx
1402 xor cx,cx
1403 @@next:
1404 mov al,[bx]
1405 cmp al,5Ch
1406 jne @@tsteos
1407 mov cx,bx
1408 @@tsteos:
1409 inc bx
1410 or al,al
1411 jnz @@next
1412 cbw
1413 jcxz @@end
1414 mov bx,cx
1415 push [word bx]
1416 mov [bx],al
1417 push bx
1418 call chdir
1419 pop bx
1420 pop [word bx]
1421 @@end:
1422 ret
1424 endp _chdirname
1427 ;***************************************************************
1428 ;char *ultoa(unsigned long n);
1429 ;***************************************************************
1430 global _ultoa:near
1431 proc _ultoa near
1433 pop ax
1434 pop cx
1435 pop dx
1436 push dx
1437 push cx
1438 push ax ; DX:CX = n
1439 push si
1440 mov si,10
1441 mov bx,offset ultoabuf+11
1442 @@loop:
1443 dec bx
1444 xchg ax,dx
1445 xor dx,dx
1446 div si ; DX:AX = 0000:hi(n)
1447 xchg ax,cx ; CX = hi(n)/10
1448 div si ; DX:AX = hi(n)%10:lo(n)
1449 xchg ax,cx ; CX = lo(n/10)
1450 xchg ax,dx ; DX = hi(n)/10 = hi(n/10)
1451 add al,'0'
1452 mov [bx],al
1453 mov ax,cx
1454 or ax,dx
1455 jnz @@loop
1456 xchg ax,bx
1457 pop si
1458 ret
1460 endp _ultoa
1463 ;***************************************************************
1464 ;unsigned long kver2ul(char *kernel_version);
1465 ;***************************************************************
1466 global _kver2ul:near
1467 proc _kver2ul near
1469 pop bx
1470 pop ax
1471 push ax
1472 push bx
1473 push bp si di
1474 xchg ax,si
1475 xor di,di
1476 push di
1477 push di
1478 mov bp,sp
1479 inc di
1480 inc di
1481 mov cl,4
1482 @@number:
1483 xor ax,ax
1484 @@digit:
1485 shl al,cl
1486 shl ax,cl
1487 lodsb
1488 sub al,30h
1489 cmp al,9
1490 jbe @@digit
1491 mov [bp+di],ah
1492 dec di
1493 jns @@number
1494 pop ax
1495 pop dx
1496 pop di si bp
1497 kver2ulret:
1498 ret
1500 endp _kver2ul
1503 ;***************************************************************
1504 ;void try_default_args();
1505 ;***************************************************************
1506 global _try_default_args:near
1507 proc _try_default_args near
1509 mov bx,offset tazboot_cmd
1510 call open
1511 jc kver2ulret
1512 mov cx,4096
1513 mov di,[_heap_top]
1514 push cx
1515 extrn read_cmdline:near
1516 jmp near read_cmdline ; read_cmdline(ax,di,cx)
1518 endp _try_default_args
1520 endif
1522 ends _TEXT
1524 end
1526 ;###### END OF FILE ############################################