wok-current view linld/stuff/src/CRTL.ASM @ rev 19515

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents
children 7f92b23984dc
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %crefref
6 %noincl
7 %nomacs
8 p386
10 group DGROUP _TEXT,_DATA,_BSS
11 assume cs:DGROUP,ds:DGROUP
13 segment _DATA byte public use16 'DATA'
15 msg_hang db "High mem corrupted - not exiting to DOS",0
16 global _vcpi_alloc_err:byte
17 _vcpi_alloc_err db "vcpi "
18 msg_malloc db "malloc() failure",0
19 msg_crlf db 13,10,0
21 ends _DATA
23 segment _BSS byte public use16 'BSS'
25 global _heap_top:word
26 _heap_top dw ?
27 global _no_exit:byte
28 _no_exit db ?
29 filecnt db ? ; in fact 0 minus file count...
30 nextfilename dw ?
32 ends _BSS
34 segment _TEXT byte public use16 'CODE'
36 ;***************************************************************
37 ;void puts(const char* s):
38 ;void putsz(const char* s):
39 ;***************************************************************
40 global _puts:near
41 proc _puts near
43 pop ax ;caller return address
44 pop bx ; s
45 push bx
46 push ax
47 global puts:near ; puts(bx)
48 puts:
49 call putsz
50 mov bx,offset msg_crlf
51 jmp putsz
53 global _putsz:near
54 _putsz:
55 pop ax ;caller return address
56 pop bx ; s
57 push bx
58 push ax
59 global putsz:near ; putsz(bx)
60 putsz:
61 push bx
62 call strlen
63 pop dx
64 xchg ax,cx
65 mov bx,1
66 mov ah,40h
67 jmp dos
69 endp _puts
72 ;***************************************************************
73 ;int open(const char* name, int flags);
74 ;***************************************************************
75 global _open:near
76 proc _open near
78 pop cx ;caller return address
79 pop bx ; name
80 pop ax ; flags
81 push ax
82 push bx
83 push cx
84 global open:near ; open(bx,al)
85 open:
86 mov dx,bx
87 mov ah,3dh
88 dos:
89 int 21h
90 jnc doret
91 fail:
92 sbb ax,ax ; ax=-1 CF
93 cwd
94 doret:
95 ifndef NO386
96 push dx
97 push ax
98 pop eax
99 endif
100 ret
102 endp _open
105 ;***************************************************************
106 ;int close(int fd);
107 ;***************************************************************
108 global _close:near
109 proc _close near
111 pop ax ;caller return address
112 pop bx ; fd
113 push bx
114 push ax
115 global close:near ; close(bx)
116 close:
117 mov ah,3Eh
118 or bx,bx
119 jnz dos
120 ret
122 endp _close
125 ;***************************************************************
126 ;int read(int fd, void* data, int sz);
127 ;***************************************************************
128 global _read:near
129 proc _read near
131 mov ah,3fh
132 rwio:
133 ifndef NO386
134 pop dx ;caller return address
135 pop ebx ; fd & data
136 pop cx ; sz
137 push cx
138 push ebx
139 push dx
140 else
141 mov bx,sp
142 mov cx,[bx+6]
143 mov dx,[bx+4]
144 mov bx,[bx+2]
145 endif
146 clc
147 jcxz fail
148 rwioz:
149 ifndef NO386
150 push ebx
151 pop bx
152 pop dx
153 endif
154 jmp dos
156 endp _read
159 ;***************************************************************
160 ;int write(int fd, const void* data, int sz);
161 ;***************************************************************
162 global _write:near
163 proc _write near
165 mov ah,40h
166 jmp rwio
168 endp _write
171 ;***************************************************************
172 ;long lseek(int fd, long sz, int dir);
173 ;long rewind(int fd);
174 ;***************************************************************
175 global _lseek:near
176 proc _lseek near
178 ifndef NO386
179 pop ax ;caller return address
180 pop bx ; fd
181 pop ecx ; sz
182 pop dx ; dir
183 push dx
184 push ecx
185 push bx
186 push ax
187 else
188 mov bx,sp
189 mov dx,[bx+8]
190 mov cx,[bx+6]
191 mov ax,[bx+4]
192 mov bx,[bx+2]
193 endif
194 lseek:
195 xchg ax,dx ; dir
196 mov ah,42h
197 ifndef NO386
198 push ecx
199 pop dx
200 pop cx
201 endif
202 jmp dos
204 global _rewind:near
205 _rewind:
206 pop ax ;caller return address
207 pop bx ; fd
208 push bx
209 push ax
210 rewind:
211 ifndef NO386
212 xor ecx,ecx
213 xor dx,dx
214 else
215 xor ax,ax
216 xor cx,cx
217 cwd
218 endif
219 jmp lseek
221 endp _lseek
224 ;***************************************************************
225 ;int strlen(const char* s);
226 ;***************************************************************
227 global _strlen:near
228 proc _strlen near
230 pop ax ;caller return address
231 pop bx ; s
232 push bx
233 push ax
234 global strlen:near ; strlen(bx)
235 strlen:
236 mov cx,bx
237 jcxz @@end
238 dec bx
239 @@lenlp:
240 inc bx
241 cmp [byte bx],0
242 jne @@lenlp
243 sub bx,cx
244 @@end:
245 xchg ax,bx
246 ret
248 endp _strlen
251 ;***************************************************************
252 ;int strhead(const char* a,const char* b);
253 ;***************************************************************
254 global _strhead:near
255 proc _strhead near
257 pop cx ;caller return address
258 pop ax ; a
259 pop bx ; b
260 push bx
261 push ax
262 push cx
263 @@loop:
264 mov cl,[bx] ; cl = *b++
265 inc bx
266 or cl,cl ; clear C
267 jz fail ; return 0
268 xchg ax,bx
269 xor cl,[bx] ; cl -= *a++
270 and cl,0dfh ; case insensitive
271 stc
272 jnz fail ; return -1
273 inc bx
274 xchg ax,bx
275 jmp @@loop
277 endp _strhead
280 ;***************************************************************
281 ;char* malloc_or_die(unsigned size);
282 ;***************************************************************
283 global _malloc_or_die:near
284 proc _malloc_or_die near
286 pop ax ;caller return address
287 pop cx ; size
288 push cx
289 push ax
290 global malloc_or_die:near ; malloc_or_die(cx)
291 malloc_or_die:
292 call malloc
293 jz _diez
294 ret
296 endp _malloc_or_die
299 ;***************************************************************
300 ;int die(const char* msg);
301 ;int diez();
302 ;int abort();
303 ;***************************************************************
304 global _die:near
305 proc _die near
307 pop ax ;caller return address
308 pop bx ; s
309 push bx
310 push ax
311 global die:near ; die(bx)
312 die:
313 call puts
314 global _diez:near
315 _diez:
316 mov al,[_no_exit]
317 cmp al,0
318 jne @@hang
319 extrn exit:near
320 inc ax
321 jmp near exit
322 @@hang:
323 mov bx, offset msg_hang
324 call puts
325 global _abort:near
326 _abort:
327 cli
328 @@stop:
329 hlt
330 jmp @@stop
332 endp _die
335 ;***************************************************************
336 ;void next_chunk(struct image_himem *m);
337 ;***************************************************************
338 proc _next_chunk near
340 pop bx
341 pop ax
342 push ax
343 push bx
344 push di
345 xchg ax,di
346 mov bx,[di] ; m->fd
347 call close
348 ifndef NO386
349 xor eax,eax
350 else
351 xor ax,ax
352 endif
353 cwd
354 mov [di],ax ; m->fd
355 mov bx,[di+28] ; m->state
356 cmp al,[bx] ; ""
357 jz @@end
358 push si
359 mov si,bx
360 @@scan:
361 lodsb
362 mov cx,si
363 cmp al,','
364 jz @@eos
365 cmp al,0
366 jnz @@scan
367 dec cx
368 @@eos:
369 mov [di+28],cx ; m->state
370 dec si
371 push [word si]
372 mov [byte si],dl ; set temp eos
373 xchg ax,dx ; O_RDONLY
374 call open
375 pop [word si] ; restore string
376 pop si
377 jc @@die
378 mov [di],ax ; m->fd
379 mov dx,2 ; SEEK_END
380 xchg ax,bx
381 ifndef NO386
382 xor ecx,ecx
383 else
384 xor ax,ax
385 xor cx,cx
386 endif
387 call lseek
388 @@die:
389 mov bx,[di+20] ; m->errmsg
390 jc die
391 mov bx,[di] ; m->fd
392 ifndef NO386
393 push eax
394 call rewind
395 pop eax
396 @@end:
397 mov [di+22],eax ; m->chunk_size
398 else
399 push ax
400 push dx
401 call rewind
402 pop dx
403 pop ax
404 @@end:
405 mov [di+22],ax ; m->chunk_size
406 mov [di+24],dx
407 endif
408 pop di
409 ret
411 endp _next_chunk
414 ;***************************************************************
415 ;void open_image(const char *name, struct image_himem *m);
416 ;struct image_himem {
417 ; 0 int fd;
418 ; 2 u32 fallback;
419 ; 6 u32 size;
420 ;10 u32 remaining;
421 ;14 u32 buf;
422 ;18 u32 *bufv;
423 ;20 char *errmsg;
424 ;22 u32 chunk_size;
425 ;26 void (*next_chunk)(struct image_himem *);
426 ;28 u16 state;
427 ;};
428 ;***************************************************************
429 global _open_image:near
430 proc _open_image near
432 arg fname :word, \
433 m :word = PARAM_SIZE
435 push bp
436 mov bp,sp
437 push si di
438 ifndef NO386
439 xor eax,eax ; 1st loop flag + eos
440 else
441 xor ax,ax ; 1st loop flag + eos
442 endif
443 mov di,[m]
444 cmp [di],ax ; m->fd
445 jnz @@alreadydone
446 ifndef NO386
447 mov [di+6],eax ; m->size = 0L
448 else
449 mov [di+6],ax ; m->size = 0L
450 mov [di+8],ax
451 endif
452 mov [word di+26],offset _next_chunk
453 mov si,[fname]
454 mov [di+28],si ; m->state
455 @@next:
456 push di
457 call [word di+26] ; m->next_chunk()
458 pop di
459 ifndef NO386
460 add eax,3
461 and al,0FCh
462 add [di+6],eax ; m->size += m->chunk_size
463 or eax,eax
464 jnz @@next
465 else
466 mov cx,ax
467 or cx,dx
468 add ax,3
469 adc dx,0
470 and al,0FCh
471 add [di+6],ax ; m->size += m->chunk_size
472 adc [di+8],dx
473 inc cx
474 loop @@next
475 endif
476 mov [di+28],si ; m->state
477 push di
478 call [word di+26] ; m->next_chunk()
479 pop di
480 @@alreadydone:
481 push ax
482 image_done:
483 pop ax
484 pop di si bp
485 ret
487 endp _open_image
490 ;***************************************************************
491 ;int read_image(struct image_himem *m, void* data, int sz);
492 ;***************************************************************
493 global _read_image:near
494 proc _read_image near
496 arg m :word, \
497 data :word, \
498 sz :word = PARAM_SIZE
500 push bp
501 mov bp,sp
502 push si di
503 ifndef NO386
504 push 0 ; return value
505 else
506 xor ax,ax
507 push ax
508 endif
509 mov di,[m]
510 @@loop:
511 mov ax,[word sz]
512 mov cx,[di+22] ; m->chunk_size
513 cmp ax,cx
514 jb @@szok
515 cmp [word di+24],0 ; hi m->chunk_size
516 jne @@szok
517 xchg ax,cx
518 @@szok:
519 push ax
520 push [word data]
521 push [word di]
522 call _read
523 pop cx
524 pop bx
525 add bx,ax
526 pop cx
527 xor cx,cx
528 sub [di+22],ax
529 sbb [di+24],cx
530 @@fill:
531 test al,3
532 je @@filled
533 mov [bx],cl
534 inc bx
535 inc ax
536 jmp @@fill
537 @@filled:
538 add [bp-4-2],ax
539 add [word data],ax
540 sub [word sz],ax
541 jz image_done
542 mov cx,[di+22] ; lo m->chunk_size
543 or cx,[di+24] ; hi m->chunk_size
544 jnz image_done
545 or cx,[di+26] ; m->next_chunk
546 jz image_done
547 push di
548 call cx ; m->next_chunk()
549 pop di
550 mov cx,[di+22] ; lo m->chunk_size
551 or cx,[di+24] ; hi m->chunk_size
552 jz image_done
553 jmp @@loop
555 endp _read_image
558 ;***************************************************************
559 ;unsigned long strtol(const char *s);
560 ;***************************************************************
561 global _strtol:near
562 proc _strtol near
564 ;TODO NO386
565 ifndef NO386
566 pop ax ;caller return address
567 pop cx ; s
568 push cx
569 push ax
570 xor ebx,ebx
571 jcxz @@end
572 push si
573 mov si,cx
574 xor ecx,ecx
575 xor eax,eax
576 mov cl,10 ; radix
577 lodsb
578 cmp al,'+'
579 je @@radixskip
580 cmp al,'-'
581 clc
582 jne @@radixkeep
583 stc
584 @@radixskip:
585 lodsb
586 @@radixkeep:
587 pushf
588 cmp al,'0'
589 jne @@radixok
590 mov cl,8
591 lodsb
592 mov dl,20h
593 or dl,al
594 cmp dl,'x'
595 jne @@radixok
596 mov cl,16
597 @@strtollp:
598 lodsb
599 @@radixok:
600 sub al,'0'
601 jb @@endstrtol
602 cmp al,9
603 jbe @@digitok
604 or al,20h
605 cmp al,'a'-'0'
606 jb @@endstrtol
607 sub al,'a'-'0'-10
608 @@digitok:
609 cmp al,cl
610 jae @@endstrtol
611 xchg eax,ebx
612 mul ecx
613 add eax,ebx
614 xchg eax,ebx
615 jmp @@strtollp
616 @@endstrtol:
617 mov cl,10
618 cmp al,'k'-'a'+10
619 je @@shift
620 mov cl,20
621 cmp al,'m'-'a'+10
622 je @@shift
623 mov cl,30
624 cmp al,'g'-'a'+10
625 jne @@noshift
626 @@shift:
627 shl ebx,cl
628 @@noshift:
629 popf
630 jnc @@end
631 neg ebx
632 @@end:
633 push ebx
634 pop ax
635 pop dx
636 popsiret:
637 pop si
638 else
639 pop ax ;caller return address
640 pop cx ; s
641 push cx
642 push ax
643 push si
644 push di
645 xor ax,ax
646 cwd
647 xchg ax,di
648 jcxz @@end
649 mov si,cx
650 mov cx,10 ; radix
651 lodsb
652 cmp al,'+'
653 je @@radixskip
654 cmp al,'-'
655 clc
656 jne @@radixkeep
657 stc
658 @@radixskip:
659 lodsb
660 @@radixkeep:
661 pushf
662 cmp al,'0'
663 jne @@radixok
664 mov cl,8
665 lodsb
666 mov ah,20h
667 or ah,al
668 cmp ah,'x'
669 jne @@radixok
670 mov cl,16
671 @@strtollp:
672 lodsb
673 @@radixok:
674 sub al,'0'
675 jb @@endstrtol
676 cmp al,9
677 jbe @@digitok
678 or al,20h
679 cmp al,'a'-'0'
680 jb @@endstrtol
681 sub al,'a'-'0'-10
682 @@digitok:
683 cmp al,cl
684 jae @@endstrtol
686 push ax
687 push si
688 push dx
689 xchg ax,di
690 mul cx
691 xchg ax,di
692 xchg ax,dx
693 xchg ax,si
694 pop ax
695 mul cx
696 add ax,si
697 pop si
698 xchg ax,dx
699 pop ax
700 mov ah,0
701 add di,ax
702 adc dx,0
704 jmp @@strtollp
705 @@endstrtol:
706 mov cl,10
707 cmp al,'k'-'a'+10
708 je @@shift
709 mov cl,20
710 cmp al,'m'-'a'+10
711 je @@shift
712 mov cl,30
713 cmp al,'g'-'a'+10
714 jne @@noshift
715 @@shift:
716 rcl di,1
717 shl dx,1
718 loop @@shift
719 @@noshift:
720 popf
721 jnc @@end
722 not dx
723 neg di
724 jne @@end
725 inc dx
726 @@end:
727 xchg ax,di
728 pop di
729 popsiret:
730 pop si
731 endif
732 ret
734 endp _strtol
737 ;***************************************************************
738 ;>void sort(unsigned long *base:BX!, size_t nel:CX)
739 ;NO386 safe: only used by VCPI
740 ;***************************************************************
741 global _sort:near
742 proc _sort near
744 pop ax ;caller return address
745 pop bx ; base
746 pop cx ; nel
747 push cx
748 push bx
749 push ax
750 global sort:near
751 sort:
752 ifndef fastsort
753 ; bubble sort
754 push si
755 cmp cx,2
756 jl popsiret
757 shl cx,2
758 @@loop:
759 xor ax,ax
760 jcxz popsiret
761 mov si,4
762 @@next:
763 mov edx,[bx+si-4]
764 cmp edx,[bx+si]
765 jbe @@ok
766 xchg edx,[bx+si]
767 mov [bx+si-4],edx
768 mov ax,si
769 @@ok:
770 add si,4
771 cmp si,cx
772 jb @@next
773 xchg ax,cx
774 jmp @@loop
775 else
776 ; shell sort (c) uclibc GPL
777 push si di
778 ; {
779 ;> size_t wgap:SI;
780 ;
781 ; if (nel > 1) {
782 cmp cx,1
783 jbe @@end
784 ; wgap = 0;
785 xor ax,ax
786 ; do {
787 @@wgaplp:
788 mov si,ax
789 ; wgap = 3 * wgap + 1;
790 mov dx,3
791 mul dx
792 inc ax
793 ; } while (wgap < (nel-1)/3);
794 cmp ax,cx
795 jb @@wgaplp
796 ; /* From the above, we know that either wgap == 1 < nel or */
797 ; /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
798 ; wgap *= 4; /* So this can not overflow if wnel doesn't. */
799 shl si,2
800 ; nel *= 4; /* Convert nel to 'wnel' */
801 shl cx,2
802 ; do {
803 @@lp1:
804 ;> size_t i:DI;
805 ; i = wgap;
806 mov di,si
807 ; do {
808 @@lp2:
809 ;> size_t j:DX;
810 ; j = i;
811 mov dx,di
812 ; do {
813 @@lp3:
814 ;> register char *a:BX!;
815 ;
816 ; j -= wgap;
817 sub dx,si
818 ; a = j + ((char *)base);
819 push bx
820 add bx,dx
821 ; if (cmp(a, a + wgap) <= 0) {
822 mov eax,[bx]
823 cmp eax,[bx+si]
824 jbe @@brk3
825 ; break;
826 ; }
827 xchg eax,[bx+si]
828 mov [bx],eax
829 ; swap(a, a + wgap);
830 pop bx
831 ; } while (j >= wgap);
832 cmp dx,si
833 jae @@lp3
834 push bx
835 @@brk3:
836 pop bx
837 ; i += 4;
838 add di,4
839 ; } while (i < nel);
840 cmp di,cx
841 jb @@lp2
842 ; wgap = (wgap - 4)/3;
843 sub si,4
844 xchg ax,si
845 cwd
846 mov si,3
847 div si ; kill dx
848 xchg ax,si
849 ; } while (wgap);
850 or si,si
851 jnz @@lp1
852 @@end:
853 ; }
854 ;}
855 pop di si
856 ret
857 endif
859 endp _sort
862 ;***************************************************************
863 ;void* malloc(unsigned sz);
864 ;***************************************************************
865 global _malloc:near
866 proc _malloc near
868 pop ax ;caller return address
869 pop cx ; sz
870 push cx
871 push ax
872 global malloc:near ; malloc(cx)
873 malloc:
874 mov ax,[_heap_top]
875 mov bx,sp
876 sub bh,14h ; MIN_STACK=_1k+PAGE_SIZE
877 sub bx,cx
878 jb @@outofmem
879 cmp bx,ax
880 jb @@outofmem
881 add [_heap_top],cx ; _BEG has zero'd heap
882 ;mov bx,ax
883 @@zalloc:
884 ;mov [byte bx],0
885 ;inc bx ; ZF=0
886 ;loop @@zalloc
887 ret
888 @@outofmem:
889 mov bx,offset msg_malloc
890 call puts
891 xor ax,ax ; ZF=1
892 ret
894 endp _malloc
897 ifdef NO386
898 ;***************************************************************
899 ;u16 topseg();
900 ;***************************************************************
901 global _topseg:near
902 proc _topseg near
904 int 12h
905 jnc @@max640k
906 mov ax,640 ; 9000
907 @@max640k:
908 sub al,040h
909 and al,0C0h
910 mov cl,6
911 shl ax,cl
912 ret
914 endp _topseg
915 endif
918 ends _TEXT
920 end
922 ;###### END OF FILE ############################################