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

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