wok-next view linld/stuff/src/CRTL.ASM @ rev 19546

linld/tazboot: default conf in tazboot.cmd
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Dec 06 18:49:44 2016 +0100 (2016-12-06)
parents 7f92b23984dc
children 9107c8697bd1
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 global _heap_top:word
16 extrn _bss_end
17 _heap_top dw _bss_end
18 msg_hang db "High mem corrupted - not exiting to DOS"
19 msg_crlf db 13,10,0
20 vcpi_alloc_err db "vcpi "
21 msg_malloc db "malloc() failure",0
23 ends _DATA
25 segment _BSS byte public use16 'BSS'
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 ;char* strcpy(const char* a, const char* b);
38 ;***************************************************************
39 global _strcpy:near
40 proc _strcpy near
42 mov dl,0
43 cat:
44 pop ax ;caller return address
45 pop cx ; a
46 pop bx ; b
47 push bx
48 push cx
49 push ax
50 push si
51 mov si,cx
52 shr dl,1
53 jnc @@nocat
54 @@catlp:
55 lodsb
56 cmp al,0
57 jne @@catlp
58 dec si
59 shr dl,1
60 jnc @@nocat
61 cmp cx,si
62 jz @@nocat
63 mov [word si],20h
64 inc si
65 @@nocat:
66 sub bx,si
67 @@cpylp:
68 mov al,[bx+si]
69 mov [si],al
70 inc si
71 cmp al,0
72 jne @@cpylp
73 mov ax,cx
74 pop si
75 ret
77 endp _strcpy
80 ;***************************************************************
81 ;char* strcat(const char* a,const char* b);
82 ;***************************************************************
83 global _strcat:near
84 proc _strcat near
86 mov dl,1
87 jmp cat
89 endp _strcat
92 ;***************************************************************
93 ;char* strcatb(const char* a,const char* b);
94 ;***************************************************************
95 global _strcatb:near
96 proc _strcatb near
98 mov dl,3
99 jmp cat
101 endp _strcatb
104 ;***************************************************************
105 ;void* malloc(unsigned sz);
106 ;***************************************************************
107 global _malloc:near
108 proc _malloc near
110 pop ax ;caller return address
111 pop cx ; sz
112 push cx
113 push ax
114 global malloc:near ; malloc(cx)
115 malloc:
116 mov ax,[_heap_top]
117 mov bx,offset msg_malloc
118 mov dx,-1400h ; MIN_STACK=_1k+PAGE_SIZE
119 add dx,sp
120 sub dx,ax ; can't overflow
121 cmp dx,cx
122 jb puts
123 add [_heap_top],cx ; _BEG has zero'd heap
124 ;mov bx,ax
125 @@zalloc:
126 ;mov [byte bx],0
127 ;inc bx ; ZF=0
128 ;loop @@zalloc
129 ret
131 endp _malloc
134 ;***************************************************************
135 ;void puts(const char* s):
136 ;void putsz(const char* s):
137 ;***************************************************************
138 global _puts:near
139 proc _puts near
141 pop ax ;caller return address
142 pop bx ; s
143 push bx
144 push ax
145 global puts:near ; puts(bx)
146 puts:
147 call putsz
148 mov bx,offset msg_crlf
149 jmp putsz
151 global _putsz:near
152 _putsz:
153 pop ax ;caller return address
154 pop bx ; s
155 push bx
156 push ax
157 global putsz:near ; putsz(bx)
158 putsz:
159 push bx
160 call strlen
161 pop dx
162 xchg ax,cx
163 mov bx,1
164 mov ah,40h
165 int 21h
166 xor ax,ax ; ZF=1 (for malloc failure)
167 ret
169 endp _puts
172 ;***************************************************************
173 ;int fileattr(const char* name);
174 ;***************************************************************
175 global _fileattr:near
176 proc _fileattr near
178 pop ax ;caller return address
179 pop dx ; name
180 push dx
181 push ax
182 mov ax,4300h
183 int 21h
184 xchg ax,cx
185 jmp chkc
187 endp _fileattr
190 ;***************************************************************
191 ;int open(const char* name, int flags=O_RDONLY);
192 ;***************************************************************
193 global _open:near
194 proc _open near
196 pop ax ;caller return address
197 pop bx ; name
198 push bx
199 push ax
200 global open:near ; open(bx)
201 open:
202 mov dx,bx
203 mov ax,3d00h
204 dos:
205 int 21h
206 chkc:
207 jnc doret
208 fail:
209 sbb ax,ax ; ax=-1 CF
210 cwd
211 doret:
212 ifndef NO386
213 push dx ; see next_chunk:lseek
214 push ax
215 pop eax
216 endif
217 ret
219 endp _open
222 ;***************************************************************
223 ;int close(int fd);
224 ;***************************************************************
225 global _close:near
226 proc _close near
228 pop ax ;caller return address
229 pop bx ; fd
230 push bx
231 push ax
232 global close:near ; close(bx)
233 close:
234 mov ah,3Eh
235 or bx,bx
236 jnz dos
237 ret
239 endp _close
242 ;***************************************************************
243 ;int read(int fd, void* data, int sz);
244 ;***************************************************************
245 global _read:near
246 proc _read near
248 mov ah,3fh
249 rwio:
250 ifndef NO386
251 pop dx ;caller return address
252 pop ebx ; fd & data
253 pop cx ; sz
254 push cx
255 push ebx
256 push dx
257 else
258 mov bx,sp
259 mov cx,[bx+6]
260 mov dx,[bx+4]
261 mov bx,[bx+2]
262 endif
263 clc
264 jcxz fail
265 rwioz:
266 ifndef NO386
267 push ebx
268 pop bx
269 pop dx
270 endif
271 jmp dos
273 endp _read
276 ;***************************************************************
277 ;int write(int fd, const void* data, int sz);
278 ;***************************************************************
279 global _write:near
280 proc _write near
282 mov ah,40h
283 jmp rwio
285 endp _write
288 ;***************************************************************
289 ;long lseek(int fd, long sz, int dir);
290 ;***************************************************************
291 global _lseek:near
292 proc _lseek near
294 ifndef NO386
295 pop ax ;caller return address
296 pop bx ; fd
297 pop ecx ; sz
298 pop dx ; dir
299 push dx
300 push ecx
301 push bx
302 push ax
303 else
304 mov bx,sp
305 mov dx,[bx+8]
306 mov cx,[bx+6]
307 mov ax,[bx+4]
308 mov bx,[bx+2]
309 endif
310 lseek:
311 xchg ax,dx ; dir
312 mov ah,42h
313 ifndef NO386
314 push ecx
315 pop dx
316 pop cx
317 endif
318 jmp dos
320 endp _lseek
323 ;***************************************************************
324 ;int strlen(const char* s);
325 ;***************************************************************
326 global _strlen:near
327 proc _strlen near
329 pop ax ;caller return address
330 pop bx ; s
331 push bx
332 push ax
333 global strlen:near ; strlen(bx)
334 strlen:
335 mov cx,bx
336 jcxz @@end
337 dec bx
338 @@lenlp:
339 inc bx
340 cmp [byte bx],0
341 jne @@lenlp
342 sub bx,cx
343 @@end:
344 xchg ax,bx
345 ret
347 endp _strlen
350 ;***************************************************************
351 ;int strhead(const char* a,const char* b);
352 ;***************************************************************
353 global _strhead:near
354 proc _strhead near
356 pop cx ;caller return address
357 pop ax ; a
358 pop bx ; b
359 push bx
360 push ax
361 push cx
362 @@loop:
363 mov cl,[bx] ; cl = *b++
364 inc bx
365 or cl,cl ; clear C
366 jz fail ; return 0
367 xchg ax,bx
368 xor cl,[bx] ; cl -= *a++
369 and cl,0dfh ; case insensitive
370 stc
371 jnz fail ; return -1
372 inc bx
373 xchg ax,bx
374 jmp @@loop
376 endp _strhead
379 ;***************************************************************
380 ;char* malloc_or_die(unsigned size);
381 ;***************************************************************
382 global _malloc_or_die:near
383 proc _malloc_or_die near
385 pop ax ;caller return address
386 pop cx ; size
387 push cx
388 push ax
389 global malloc_or_die:near ; malloc_or_die(cx)
390 malloc_or_die:
391 call malloc
392 jz _exit
393 ret
395 endp _malloc_or_die
398 ;***************************************************************
399 ;int die(const char* msg);
400 ;int exit();
401 ;int abort();
402 ;***************************************************************
403 global _die:near
404 proc _die near
406 pop ax ;caller return address
407 pop bx ; s
408 push bx
409 push ax
410 global die:near ; die(bx)
411 die:
412 call puts
413 global _exit:near
414 _exit:
415 mov al,[_no_exit]
416 cmp al,0
417 jne @@hang
418 extrn exit:near
419 inc ax
420 jmp near exit
421 @@hang:
422 mov bx, offset msg_hang
423 call puts
424 global _abort:near
425 _abort:
426 cli
427 @@stop:
428 hlt
429 jmp @@stop
431 endp _die
433 struc image_himem ;struct image_himem {
434 fd dw ? ; 0 int fd;
435 fallback dd ? ; 2 u32 fallback;
436 size dd ? ; 6 u32 size;
437 remaining dd ? ;10 u32 remaining;
438 buf dd ? ;14 u32 buf;
439 bufv dw ? ;18 u32 *bufv;
440 errmsg dw ? ;20 char *errmsg;
441 chunk_size dd ? ;22 u32 chunk_size;
442 next_chunk dw ? ;26 void (*next_chunk)(struct image_himem *);
443 state dw ? ;28 u16 state;
444 fd2close dw ? ;30 u16 fd2close;
445 ends ;};
447 ;***************************************************************
448 ;u32* malloc_bufv_or_die(struct image_himem *m);
449 ;***************************************************************
450 global _malloc_bufv_or_die:near
451 proc _malloc_bufv_or_die near
453 pop bx ;caller return address
454 pop ax
455 push ax
456 push bx
457 push si
458 xchg ax,si
459 mov ecx,[(image_himem si).size]
460 dec ecx
461 shr ecx,12
462 inc cx ; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
463 push cx
464 inc cx ; cnt+1
465 shl cx,2 ; bufv => vcpi => vm86
466 ; our malloc zeroes allocated mem: bufv[cnt]=0;
467 ; Allocate pages, storing addrs in addrbuf
468 call malloc_or_die
469 pop cx
470 push cx ; _sort:nel
471 push ax ; _sort:base
472 mov [(image_himem si).bufv],ax
473 xchg ax,bx
474 @@vcpi_alloc:
475 xor edx,edx
476 mov ax,0DE04h
477 int 67h
478 or ah,ah
479 jz @@ok
480 mov bx,offset vcpi_alloc_err
481 jmp die
482 @@ok:
483 mov [bx],edx
484 add bx,4
485 loop @@vcpi_alloc
486 @@again:
487 call _sort
488 extrn _initrd
489 cmp si,offset _initrd
490 jne @@quit
491 pop ax
492 pop cx
493 push cx ; _sort:nel
494 push ax ; _sort:base = m->bufv
495 ;again:
496 ; for (i = cnt-1; i >= 0; i--) {
497 @@chkloop:
498 mov bx,cx
499 dec bx
500 ; if (m->bufv[i] > m->fallback+i*_4k && m->bufv[i] < m->fallback+m->size) {
501 shl bx,2
502 add bx,ax ; m->bufv
503 mov edx,[bx] ; m->bufv[i]
504 sub edx,[(image_himem si).fallback]
505 cmp edx,[(image_himem si).size]
506 jae @@chknext
507 shr edx,12
508 cmp dx,cx
509 jb @@chknext
510 ; m->bufv[i] = vcpi_alloc_or_die();
511 ; sort(m->bufv,cnt);
512 ; goto again;
513 mov cx,1
514 jmp @@vcpi_alloc
515 ; }
516 ; }
517 @@chknext:
518 loop @@chkloop
519 @@quit:
520 pop ax
521 pop cx
522 pop si
523 ret
525 endp _malloc_bufv_or_die
528 ;***************************************************************
529 ;void next_chunk(struct image_himem *m);
530 ;***************************************************************
531 proc _next_chunk near
533 pop bx
534 pop ax
535 push ax
536 push bx
537 push si di
538 xchg ax,di
539 mov bx,[(image_himem di).fd]
540 call close
541 ifndef NO386
542 xor eax,eax
543 else
544 xor ax,ax
545 endif
546 cwd
547 mov [(image_himem di).fd],ax
548 mov bx,[(image_himem di).state]
549 cmp al,[bx] ; ""
550 jz @@end
551 mov si,bx
552 @@scan:
553 lodsb
554 mov cx,si
555 cmp al,','
556 jz @@eos
557 cmp al,0
558 jnz @@scan
559 dec cx
560 @@eos:
561 mov [(image_himem di).state],cx
562 dec si
563 push [word si]
564 mov [byte si],dl ; set temp eos
565 call open
566 pop [word si] ; restore string
567 jc @@die
568 mov [(image_himem di).fd],ax
569 mov [(image_himem di).fd2close],ax
570 mov dx,2 ; SEEK_END
571 xchg ax,bx
572 ifndef NO386
573 xor ecx,ecx
574 else
575 xor ax,ax
576 xor cx,cx
577 endif
578 call lseek
579 @@die:
580 mov bx,[(image_himem di).errmsg]
581 jc die
582 mov bx,[(image_himem di).fd]
583 ifndef NO386
584 push eax
585 xor ecx,ecx
586 xor dx,dx
587 call lseek ; rewind
588 pop eax
589 @@end:
590 mov [(image_himem di).chunk_size],eax
591 else
592 push ax
593 push dx
594 xor ax,ax
595 xor cx,cx
596 cwd
597 call lseek ; rewind
598 pop dx
599 pop ax
600 @@end:
601 mov [word (image_himem di).chunk_size],ax
602 mov [word ((image_himem di).chunk_size)+2],dx
603 endif
604 pop di si
605 ret
607 endp _next_chunk
610 ;***************************************************************
611 ;void open_image(const char *name, struct image_himem *m);
612 ;***************************************************************
613 global _open_image:near
614 proc _open_image near
616 arg fname :word, \
617 m :word = PARAM_SIZE
619 push bp
620 mov bp,sp
621 push si di
622 ifndef NO386
623 xor eax,eax ; 1st loop flag + eos
624 else
625 xor ax,ax ; 1st loop flag + eos
626 endif
627 mov di,[m]
628 cmp [(image_himem di).fd],ax
629 jnz @@alreadydone
630 ifndef NO386
631 mov [(image_himem di).size],eax ; m->size = 0L
632 else
633 mov [word (image_himem di).size],ax ; m->size = 0L
634 mov [word ((image_himem di).size)+2],ax
635 endif
636 mov [(image_himem di).next_chunk],offset _next_chunk
637 mov si,[fname]
638 mov [(image_himem di).state],si
639 @@next:
640 push di
641 call [(image_himem di).next_chunk] ; m->next_chunk()
642 pop di
643 ifndef NO386
644 add eax,3
645 and al,0FCh
646 add [(image_himem di).size],eax ; m->size += m->chunk_size
647 or eax,eax
648 jnz @@next
649 else
650 mov cx,ax
651 or cx,dx
652 add ax,3
653 adc dx,0
654 and al,0FCh
655 add [word (image_himem di).size],ax ; m->size += m->chunk_size
656 adc [word ((image_himem di).size)+2],dx
657 inc cx ; jcxnz
658 loop @@next
659 endif
660 mov [(image_himem di).state],si
661 push di
662 call [(image_himem di).next_chunk] ; m->next_chunk()
663 pop di
664 @@alreadydone:
665 push ax
666 image_done:
667 pop ax
668 pop di si bp
669 ret
671 endp _open_image
674 ;***************************************************************
675 ;int read_image(struct image_himem *m, void* data, int sz);
676 ;***************************************************************
677 global _read_image:near
678 proc _read_image near
680 arg m :word, \
681 data :word, \
682 sz :word = PARAM_SIZE
684 push bp
685 mov bp,sp
686 push si di
687 ifndef NO386
688 push 0 ; return value
689 else
690 xor ax,ax
691 push ax
692 endif
693 mov di,[m]
694 @@loop:
695 ifndef NO386
696 xor ecx,ecx
697 mov cx,[word sz]
698 @@chksz:
699 mov eax,[(image_himem di).chunk_size]
700 cmp ecx,eax
701 jb @@szok
702 xchg eax,ecx
703 else
704 mov cx,[word sz]
705 @@chksz:
706 mov ax,[word (image_himem di).chunk_size]
707 cmp cx,ax
708 jb @@szok
709 cmp [word ((image_himem di).chunk_size)+2],0 ; hi m->chunk_size
710 jne @@szok
711 xchg ax,cx
712 endif
713 @@szok:
714 jcxz image_done
715 push cx
716 push [word data]
717 push [word di]
718 call _read
719 pop dx
720 pop bx
721 pop dx
722 jc image_done
723 add bx,ax
724 xor cx,cx
725 ifndef NO386
726 cwde ; ax < 8000h
727 cwd
728 sub [(image_himem di).chunk_size],eax
729 else
730 cwd ; ax < 8000h
731 sub [word (image_himem di).chunk_size],ax
732 sbb [word ((image_himem di).chunk_size)+2],dx
733 jnz @@fill
734 cmp [word (image_himem di).chunk_size],dx
735 endif
736 jnz @@fill
737 dec cx
738 @@fill:
739 test al,3
740 je @@filled
741 mov [bx],dl
742 inc bx
743 inc ax
744 jmp @@fill
745 @@filled:
746 ifndef NO386
747 sub [(image_himem di).remaining],eax
748 else
749 sub [word (image_himem di).remaining],ax
750 sbb [word ((image_himem di).remaining)+2],dx
751 endif
752 add [bp-4-2],ax
753 add [word data],ax
754 sub [word sz],ax
755 pushf
756 and cx,[(image_himem di).next_chunk]
757 jz @@same_chunk
758 push di
759 call cx ; m->next_chunk()
760 pop di
761 @@same_chunk:
762 popf
763 jnz @@loop
764 jmp image_done
766 endp _read_image
769 ;***************************************************************
770 ;unsigned long strtol(const char *s);
771 ;***************************************************************
772 global _strtol:near
773 proc _strtol near
775 ifndef NO386
776 pop ax ;caller return address
777 pop cx ; s
778 push cx
779 push ax
780 xor ebx,ebx
781 jcxz @@jncend
782 push si
783 mov si,cx
784 xor ecx,ecx
785 xor eax,eax
786 lodsb
787 mov dl,20h
788 or dl,al
789 cmp dl,'n' ; vga=normal
790 je @@vga
791 dec cx
792 cmp dl,'e' ; vga=extended
793 je @@vga
794 dec cx
795 cmp dl,'a' ; vga=ask
796 jne @@notvga
797 @@vga:
798 dec cx
799 xchg ax,cx
800 cwd
801 jmp popsiret
802 @@notvga:
803 mov cx,10 ; radix
804 cmp al,'+'
805 je @@radixskip
806 cmp al,'-'
807 clc
808 jne @@radixkeep
809 stc
810 @@radixskip:
811 lodsb
812 @@radixkeep:
813 pushf
814 cmp al,'0'
815 jne @@radixok
816 mov cl,8
817 lodsb
818 mov dl,20h
819 or dl,al
820 cmp dl,'x'
821 jne @@radixok
822 mov cl,16
823 @@strtollp:
824 lodsb
825 @@radixok:
826 sub al,'0'
827 jb @@endstrtol
828 cmp al,9
829 jbe @@digitok
830 or al,20h
831 cmp al,'a'-'0'
832 jb @@endstrtol
833 sub al,'a'-'0'-10
834 @@digitok:
835 cmp al,cl
836 jae @@endstrtol
837 xchg eax,ebx
838 mul ecx
839 add eax,ebx
840 xchg eax,ebx
841 jmp @@strtollp
842 @@endstrtol:
843 mov cl,10
844 cmp al,'k'-'a'+10
845 je @@shift
846 mov cl,20
847 cmp al,'m'-'a'+10
848 je @@shift
849 mov cl,30
850 cmp al,'g'-'a'+10
851 jne @@noshift
852 @@shift:
853 shl ebx,cl
854 @@noshift:
855 popf
856 @@jncend:
857 jnc @@end
858 neg ebx
859 @@end:
860 push ebx
861 pop ax
862 pop dx
863 popsiret:
864 pop si
865 else
866 pop ax ;caller return address
867 pop cx ; s
868 push cx
869 push ax
870 push si
871 push di
872 xor ax,ax
873 cwd
874 xchg ax,di
875 jcxz @@goend
876 mov si,cx
877 lodsb
878 mov dl,20h
879 or dl,al
880 mov cx,-1
881 cmp dl,'n' ; vga=normal
882 je @@vga
883 dec cx
884 cmp dl,'e' ; vga=extended
885 je @@vga
886 dec cx
887 cmp dl,'a' ; vga=ask
888 jne @@notvga
889 @@vga:
890 xchg ax,cx
891 cwd
892 jmp popsiret
893 @@goend:
894 jmp @@end
895 @@notvga:
896 mov cx,10 ; radix
897 cmp al,'+'
898 je @@radixskip
899 cmp al,'-'
900 clc
901 jne @@radixkeep
902 stc
903 @@radixskip:
904 lodsb
905 @@radixkeep:
906 pushf
907 cmp al,'0'
908 jne @@radixok
909 mov cl,8
910 lodsb
911 mov ah,20h
912 or ah,al
913 cmp ah,'x'
914 jne @@radixok
915 mov cl,16
916 @@strtollp:
917 lodsb
918 @@radixok:
919 sub al,'0'
920 jb @@endstrtol
921 cmp al,9
922 jbe @@digitok
923 or al,20h
924 cmp al,'a'-'0'
925 jb @@endstrtol
926 sub al,'a'-'0'-10
927 @@digitok:
928 cmp al,cl
929 jae @@endstrtol
931 push ax
932 push si
933 push dx
934 xchg ax,di
935 mul cx
936 xchg ax,di
937 xchg ax,dx
938 xchg ax,si
939 pop ax
940 mul cx
941 add ax,si
942 pop si
943 xchg ax,dx
944 pop ax
945 mov ah,0
946 add di,ax
947 adc dx,0
949 jmp @@strtollp
950 @@endstrtol:
951 mov cl,10
952 cmp al,'k'-'a'+10
953 je @@shift
954 mov cl,20
955 cmp al,'m'-'a'+10
956 je @@shift
957 mov cl,30
958 cmp al,'g'-'a'+10
959 jne @@noshift
960 @@shift:
961 rcl di,1
962 shl dx,1
963 loop @@shift
964 @@noshift:
965 popf
966 jnc @@end
967 not dx
968 neg di
969 jne @@end
970 inc dx
971 @@end:
972 xchg ax,di
973 pop di
974 popsiret:
975 pop si
976 endif
977 ret
979 endp _strtol
982 ;***************************************************************
983 ;>void sort(unsigned long *base:BX!, size_t nel:CX)
984 ;NO386 safe: only used by VCPI
985 ;***************************************************************
986 global _sort:near
987 proc _sort near
989 pop ax ;caller return address
990 pop bx ; base
991 pop cx ; nel
992 push cx
993 push bx
994 push ax
995 global sort:near
996 sort:
997 ifndef fastsort
998 ; bubble sort
999 push si
1000 shl cx,2
1001 @@loop:
1002 xor ax,ax
1003 mov si,4
1004 cmp cx,si
1005 jbe popsiret
1006 @@next:
1007 mov edx,[bx+si-4]
1008 cmp edx,[bx+si]
1009 jbe @@ok
1010 xchg edx,[bx+si]
1011 mov [bx+si-4],edx
1012 mov ax,si
1013 @@ok:
1014 add si,4
1015 cmp si,cx
1016 jb @@next
1017 xchg ax,cx
1018 jmp @@loop
1019 else
1020 ; shell sort (c) uclibc GPL
1021 push si di
1022 ; {
1023 ;> size_t wgap:SI;
1025 ; if (nel > 1) {
1026 cmp cx,1
1027 jbe @@end
1028 ; wgap = 0;
1029 xor ax,ax
1030 ; do {
1031 @@wgaplp:
1032 mov si,ax
1033 ; wgap = 3 * wgap + 1;
1034 mov dx,3
1035 mul dx
1036 inc ax
1037 ; } while (wgap < (nel-1)/3);
1038 cmp ax,cx
1039 jb @@wgaplp
1040 ; /* From the above, we know that either wgap == 1 < nel or */
1041 ; /* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap < nel. */
1042 ; wgap *= 4; /* So this can not overflow if wnel doesn't. */
1043 shl si,2
1044 ; nel *= 4; /* Convert nel to 'wnel' */
1045 shl cx,2
1046 ; do {
1047 @@lp1:
1048 ;> size_t i:DI;
1049 ; i = wgap;
1050 mov di,si
1051 ; do {
1052 @@lp2:
1053 ;> size_t j:DX;
1054 ; j = i;
1055 mov dx,di
1056 ; do {
1057 @@lp3:
1058 ;> register char *a:BX!;
1060 ; j -= wgap;
1061 sub dx,si
1062 ; a = j + ((char *)base);
1063 push bx
1064 add bx,dx
1065 ; if (cmp(a, a + wgap) <= 0) {
1066 mov eax,[bx]
1067 cmp eax,[bx+si]
1068 jbe @@brk3
1069 ; break;
1070 ; }
1071 xchg eax,[bx+si]
1072 mov [bx],eax
1073 ; swap(a, a + wgap);
1074 pop bx
1075 ; } while (j >= wgap);
1076 cmp dx,si
1077 jae @@lp3
1078 push bx
1079 @@brk3:
1080 pop bx
1081 ; i += 4;
1082 add di,4
1083 ; } while (i < nel);
1084 cmp di,cx
1085 jb @@lp2
1086 ; wgap = (wgap - 4)/3;
1087 sub si,4
1088 xchg ax,si
1089 cwd
1090 mov si,3
1091 div si ; kill dx
1092 xchg ax,si
1093 ; } while (wgap);
1094 or si,si
1095 jnz @@lp1
1096 @@end:
1097 ; }
1098 ;}
1099 pop di si
1100 ret
1101 endif
1103 endp _sort
1106 ifdef NO386
1107 ;***************************************************************
1108 ;u16 topseg();
1109 ;***************************************************************
1110 global _topseg:near
1111 proc _topseg near
1113 int 12h
1114 jnc @@max640k
1115 mov ax,640 ; 9000
1116 @@max640k:
1117 sub ax,028h
1118 and al,0C0h
1119 mov cl,6
1120 shl ax,cl
1121 ret
1123 endp _topseg
1124 endif
1126 ;***************************************************************
1127 ;void rmcpy(void* rmbuf, u16 rmsize);
1128 ;***************************************************************
1129 global _rmcpy:near
1130 proc _rmcpy near
1132 pop bx ;caller return address
1133 pop ax ; rmbuf
1134 pop cx ; rmsize
1135 push cx
1136 push ax
1137 push bx
1138 push si di es
1139 xchg ax,si
1140 xor di,di
1141 ifdef NO386
1142 call _topseg
1143 mov es,ax
1144 else
1145 push 9000h
1146 pop es
1147 endif
1148 cld
1149 rep
1150 movsb
1151 extrn _cmdline:word
1152 mov si,[_cmdline]
1153 mov di,8000h
1154 mov ch,10h ; 4k
1155 rep
1156 movsb
1157 pop es di si
1158 ret
1160 endp _rmcpy
1162 ends _TEXT
1164 end
1166 ;###### END OF FILE ############################################