wok diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linld/stuff/src/CRTL.ASM	Tue Nov 22 21:19:01 2016 +0100
     1.3 @@ -0,0 +1,922 @@
     1.4 +;***************************************************************
     1.5 +;****** This file is distributed under GPL
     1.6 +;***************************************************************
     1.7 +                ideal
     1.8 +                %crefref
     1.9 +                %noincl
    1.10 +                %nomacs
    1.11 +                p386
    1.12 +
    1.13 +        group   DGROUP  _TEXT,_DATA,_BSS
    1.14 +        assume  cs:DGROUP,ds:DGROUP
    1.15 +
    1.16 +        segment _DATA byte public use16 'DATA'
    1.17 +
    1.18 +msg_hang	db      "High mem corrupted - not exiting to DOS",0
    1.19 +        global  _vcpi_alloc_err:byte
    1.20 +_vcpi_alloc_err	db	"vcpi "
    1.21 +msg_malloc      db      "malloc() failure",0
    1.22 +msg_crlf	db	13,10,0
    1.23 +
    1.24 +        ends    _DATA
    1.25 +
    1.26 +        segment _BSS byte public use16 'BSS'
    1.27 +
    1.28 +        global  _heap_top:word
    1.29 +_heap_top	dw	?
    1.30 +        global  _no_exit:byte
    1.31 +_no_exit	db	?
    1.32 +filecnt		db	?		; in fact 0 minus file count...
    1.33 +nextfilename	dw	?
    1.34 +
    1.35 +        ends    _BSS
    1.36 +
    1.37 +        segment _TEXT byte public use16 'CODE'
    1.38 +
    1.39 +;***************************************************************
    1.40 +;void puts(const char* s):
    1.41 +;void putsz(const char* s):
    1.42 +;***************************************************************
    1.43 +        global  _puts:near
    1.44 +        proc    _puts near
    1.45 +
    1.46 +		pop	ax			;caller return address
    1.47 +                pop	bx			; s
    1.48 +                push	bx
    1.49 +                push	ax
    1.50 +        global  puts:near			; puts(bx)
    1.51 +puts:
    1.52 +		call	putsz
    1.53 +                mov	bx,offset msg_crlf
    1.54 +		jmp	putsz
    1.55 +
    1.56 +        global  _putsz:near
    1.57 +_putsz:
    1.58 +		pop	ax			;caller return address
    1.59 +                pop	bx			; s
    1.60 +                push	bx
    1.61 +                push	ax
    1.62 +        global  putsz:near			; putsz(bx)
    1.63 +putsz:
    1.64 +                push	bx
    1.65 +		call	strlen
    1.66 +		pop	dx
    1.67 +		xchg	ax,cx
    1.68 +		mov	bx,1
    1.69 +                mov	ah,40h
    1.70 +		jmp	dos
    1.71 +
    1.72 +        endp    _puts
    1.73 +
    1.74 +
    1.75 +;***************************************************************
    1.76 +;int open(const char* name, int flags);
    1.77 +;***************************************************************
    1.78 +        global  _open:near
    1.79 +        proc    _open near
    1.80 +
    1.81 +		pop	cx			;caller return address
    1.82 +                pop	bx			; name
    1.83 +                pop	ax			; flags
    1.84 +                push	ax
    1.85 +                push	bx
    1.86 +                push	cx
    1.87 +        global  open:near			; open(bx,al)
    1.88 +open:
    1.89 +                mov	dx,bx
    1.90 +                mov	ah,3dh
    1.91 +dos:
    1.92 +                int	21h
    1.93 +                jnc	doret
    1.94 +fail:
    1.95 +                sbb	ax,ax			; ax=-1 CF
    1.96 +		cwd
    1.97 +doret:
    1.98 +		ifndef	NO386
    1.99 +                push	dx
   1.100 +                push	ax
   1.101 +                pop	eax
   1.102 +		endif
   1.103 +                ret
   1.104 +
   1.105 +        endp    _open
   1.106 +
   1.107 +
   1.108 +;***************************************************************
   1.109 +;int close(int fd);
   1.110 +;***************************************************************
   1.111 +        global  _close:near
   1.112 +        proc    _close near
   1.113 +
   1.114 +		pop	ax			;caller return address
   1.115 +                pop	bx			; fd
   1.116 +                push	bx
   1.117 +                push	ax
   1.118 +        global  close:near			; close(bx)
   1.119 +close:
   1.120 +		mov	ah,3Eh
   1.121 +		or	bx,bx
   1.122 +		jnz	dos
   1.123 +		ret
   1.124 +
   1.125 +        endp    _close
   1.126 +
   1.127 +
   1.128 +;***************************************************************
   1.129 +;int read(int fd, void* data, int sz);
   1.130 +;***************************************************************
   1.131 +        global  _read:near
   1.132 +        proc    _read near
   1.133 +
   1.134 +                mov	ah,3fh
   1.135 +rwio:
   1.136 +		ifndef	NO386
   1.137 +		pop	dx			;caller return address
   1.138 +                pop	ebx			; fd & data
   1.139 +                pop	cx			; sz
   1.140 +                push	cx
   1.141 +                push	ebx
   1.142 +                push	dx
   1.143 +		else
   1.144 +		mov	bx,sp
   1.145 +		mov	cx,[bx+6]
   1.146 +		mov	dx,[bx+4]
   1.147 +		mov	bx,[bx+2]
   1.148 +		endif
   1.149 +                clc
   1.150 +                jcxz	fail
   1.151 +rwioz:
   1.152 +		ifndef	NO386
   1.153 +                push	ebx
   1.154 +                pop	bx
   1.155 +                pop	dx
   1.156 +		endif
   1.157 +		jmp	dos
   1.158 +
   1.159 +        endp    _read
   1.160 +
   1.161 +
   1.162 +;***************************************************************
   1.163 +;int write(int fd, const void* data, int sz);
   1.164 +;***************************************************************
   1.165 +        global  _write:near
   1.166 +        proc    _write near
   1.167 +
   1.168 +                mov	ah,40h
   1.169 +		jmp	rwio
   1.170 +
   1.171 +        endp    _write
   1.172 +
   1.173 +
   1.174 +;***************************************************************
   1.175 +;long lseek(int fd, long sz, int dir);
   1.176 +;long rewind(int fd);
   1.177 +;***************************************************************
   1.178 +        global  _lseek:near
   1.179 +        proc    _lseek near
   1.180 +
   1.181 +		ifndef	NO386
   1.182 +		pop	ax			;caller return address
   1.183 +                pop	bx			; fd
   1.184 +                pop	ecx			; sz
   1.185 +                pop	dx			; dir
   1.186 +                push	dx
   1.187 +                push	ecx
   1.188 +                push	bx
   1.189 +                push	ax
   1.190 +		else
   1.191 +		mov	bx,sp
   1.192 +		mov	dx,[bx+8]
   1.193 +		mov	cx,[bx+6]
   1.194 +		mov	ax,[bx+4]
   1.195 +		mov	bx,[bx+2]
   1.196 +		endif
   1.197 +lseek:
   1.198 +		xchg	ax,dx			; dir
   1.199 +                mov	ah,42h
   1.200 +		ifndef	NO386
   1.201 +                push	ecx
   1.202 +                pop	dx
   1.203 +                pop	cx
   1.204 +		endif
   1.205 +		jmp	dos
   1.206 +
   1.207 +        global  _rewind:near
   1.208 +_rewind:
   1.209 +		pop	ax			;caller return address
   1.210 +                pop	bx			; fd
   1.211 +                push	bx
   1.212 +                push	ax
   1.213 +rewind:
   1.214 +		ifndef	NO386
   1.215 +		xor	ecx,ecx
   1.216 +		xor	dx,dx
   1.217 +		else
   1.218 +		xor	ax,ax
   1.219 +		xor	cx,cx
   1.220 +		cwd
   1.221 +		endif
   1.222 +		jmp	lseek
   1.223 +
   1.224 +        endp    _lseek
   1.225 +
   1.226 +
   1.227 +;***************************************************************
   1.228 +;int strlen(const char* s);
   1.229 +;***************************************************************
   1.230 +        global  _strlen:near
   1.231 +        proc    _strlen near
   1.232 +
   1.233 +		pop	ax			;caller return address
   1.234 +                pop	bx			; s
   1.235 +                push	bx
   1.236 +                push	ax
   1.237 +        global  strlen:near			; strlen(bx)
   1.238 +strlen:
   1.239 +                mov	cx,bx
   1.240 +                jcxz	@@end
   1.241 +                dec	bx
   1.242 +@@lenlp:
   1.243 +                inc	bx
   1.244 +                cmp	[byte bx],0
   1.245 +                jne	@@lenlp
   1.246 +                sub	bx,cx
   1.247 +@@end:
   1.248 +                xchg	ax,bx
   1.249 +                ret
   1.250 +
   1.251 +        endp    _strlen
   1.252 +
   1.253 +
   1.254 +;***************************************************************
   1.255 +;int strhead(const char* a,const char* b);
   1.256 +;***************************************************************
   1.257 +        global  _strhead:near
   1.258 +        proc    _strhead near
   1.259 +
   1.260 +		pop	cx			;caller return address
   1.261 +                pop	ax			; a
   1.262 +                pop	bx			; b
   1.263 +                push	bx
   1.264 +                push	ax
   1.265 +                push	cx
   1.266 +@@loop:
   1.267 +                mov	cl,[bx]			; cl = *b++
   1.268 +                inc	bx
   1.269 +		or	cl,cl			; clear C
   1.270 +		jz	fail			; return 0
   1.271 +		xchg	ax,bx
   1.272 +                xor	cl,[bx]			; cl -= *a++
   1.273 +		and	cl,0dfh			; case insensitive
   1.274 +		stc
   1.275 +		jnz	fail			; return -1
   1.276 +                inc	bx
   1.277 +		xchg	ax,bx
   1.278 +                jmp	@@loop
   1.279 +
   1.280 +        endp    _strhead
   1.281 +
   1.282 +
   1.283 +;***************************************************************
   1.284 +;char* malloc_or_die(unsigned size);
   1.285 +;***************************************************************
   1.286 +        global  _malloc_or_die:near
   1.287 +        proc    _malloc_or_die near
   1.288 +
   1.289 +		pop	ax			;caller return address
   1.290 +                pop	cx			; size
   1.291 +                push	cx
   1.292 +                push	ax
   1.293 +        global  malloc_or_die:near		; malloc_or_die(cx)
   1.294 +malloc_or_die:
   1.295 +		call	malloc
   1.296 +		jz	_diez
   1.297 +		ret
   1.298 +
   1.299 +        endp    _malloc_or_die
   1.300 +
   1.301 +
   1.302 +;***************************************************************
   1.303 +;int die(const char* msg);
   1.304 +;int diez();
   1.305 +;int abort();
   1.306 +;***************************************************************
   1.307 +        global  _die:near
   1.308 +        proc    _die near
   1.309 +
   1.310 +		pop	ax			;caller return address
   1.311 +                pop	bx			; s
   1.312 +                push	bx
   1.313 +                push	ax
   1.314 +        global  die:near			; die(bx)
   1.315 +die:
   1.316 +		call	puts
   1.317 +        global  _diez:near
   1.318 +_diez:
   1.319 +		mov	al,[_no_exit]
   1.320 +		cmp	al,0
   1.321 +		jne	@@hang
   1.322 +		extrn	exit:near
   1.323 +		inc	ax
   1.324 +		jmp	near exit
   1.325 +@@hang:
   1.326 +		mov	bx, offset msg_hang
   1.327 +		call	puts
   1.328 +        global  _abort:near
   1.329 +_abort:
   1.330 +		cli
   1.331 +@@stop:
   1.332 +		hlt
   1.333 +		jmp	@@stop
   1.334 +
   1.335 +        endp    _die
   1.336 +
   1.337 +
   1.338 +;***************************************************************
   1.339 +;void next_chunk(struct image_himem *m);
   1.340 +;***************************************************************
   1.341 +        proc    _next_chunk near
   1.342 +
   1.343 +		pop	bx
   1.344 +		pop	ax
   1.345 +		push	ax
   1.346 +		push	bx
   1.347 +		push	di
   1.348 +		xchg	ax,di
   1.349 +		mov	bx,[di]			; m->fd
   1.350 +		call	close
   1.351 +		ifndef	NO386
   1.352 +		xor	eax,eax
   1.353 +		else
   1.354 +		xor	ax,ax
   1.355 +		endif
   1.356 +		cwd
   1.357 +		mov	[di],ax			; m->fd
   1.358 +		mov	bx,[di+28]		; m->state
   1.359 +		cmp	al,[bx]			; ""
   1.360 +		jz	@@end
   1.361 +		push	si
   1.362 +		mov	si,bx
   1.363 +@@scan:
   1.364 +		lodsb
   1.365 +		mov	cx,si
   1.366 +		cmp	al,','
   1.367 +		jz	@@eos
   1.368 +		cmp	al,0
   1.369 +		jnz	@@scan
   1.370 +		dec	cx
   1.371 +@@eos:
   1.372 +		mov	[di+28],cx		; m->state
   1.373 +		dec	si
   1.374 +		push	[word si]
   1.375 +		mov	[byte si],dl		; set temp eos
   1.376 +		xchg	ax,dx			; O_RDONLY
   1.377 +		call	open
   1.378 +		pop	[word si]		; restore string
   1.379 +		pop	si
   1.380 +		jc	@@die
   1.381 +		mov	[di],ax			; m->fd
   1.382 +		mov	dx,2			; SEEK_END
   1.383 +		xchg	ax,bx
   1.384 +		ifndef	NO386
   1.385 +		xor	ecx,ecx
   1.386 +		else
   1.387 +		xor	ax,ax
   1.388 +		xor	cx,cx
   1.389 +		endif
   1.390 +		call	lseek
   1.391 +@@die:
   1.392 +		mov	bx,[di+20]		; m->errmsg
   1.393 +		jc	die
   1.394 +		mov	bx,[di]			; m->fd
   1.395 +		ifndef	NO386
   1.396 +		push	eax
   1.397 +		call	rewind
   1.398 +		pop	eax
   1.399 +@@end:
   1.400 +		mov	[di+22],eax		; m->chunk_size
   1.401 +		else
   1.402 +		push	ax
   1.403 +		push	dx
   1.404 +		call	rewind
   1.405 +		pop	dx
   1.406 +		pop	ax
   1.407 +@@end:
   1.408 +		mov	[di+22],ax		; m->chunk_size
   1.409 +		mov	[di+24],dx
   1.410 +		endif
   1.411 +		pop	di
   1.412 +		ret
   1.413 +
   1.414 +        endp    _next_chunk
   1.415 +
   1.416 +
   1.417 +;***************************************************************
   1.418 +;void open_image(const char *name, struct image_himem *m);
   1.419 +;struct image_himem {
   1.420 +; 0    int fd;
   1.421 +; 2    u32 fallback;
   1.422 +; 6    u32 size;
   1.423 +;10    u32 remaining;
   1.424 +;14    u32 buf;
   1.425 +;18    u32 *bufv;
   1.426 +;20    char *errmsg;
   1.427 +;22    u32 chunk_size;
   1.428 +;26    void (*next_chunk)(struct image_himem *);
   1.429 +;28    u16 state;
   1.430 +;};
   1.431 +;***************************************************************
   1.432 +        global  _open_image:near
   1.433 +        proc    _open_image near
   1.434 +
   1.435 +		arg	fname	:word,	\
   1.436 +			m	:word	= PARAM_SIZE
   1.437 +
   1.438 +		push	bp
   1.439 +		mov	bp,sp
   1.440 +                push	si di
   1.441 +		ifndef	NO386
   1.442 +                xor	eax,eax			; 1st loop flag + eos
   1.443 +		else
   1.444 +                xor	ax,ax			; 1st loop flag + eos
   1.445 +		endif
   1.446 +                mov	di,[m]
   1.447 +                cmp	[di],ax			; m->fd
   1.448 +                jnz	@@alreadydone
   1.449 +		ifndef	NO386
   1.450 +		mov	[di+6],eax		; m->size = 0L
   1.451 +		else
   1.452 +		mov	[di+6],ax		; m->size = 0L
   1.453 +		mov	[di+8],ax
   1.454 +		endif
   1.455 +		mov	[word di+26],offset _next_chunk
   1.456 +                mov	si,[fname]
   1.457 +                mov	[di+28],si		; m->state
   1.458 +@@next:
   1.459 +		push	di
   1.460 +                call	[word di+26]		; m->next_chunk()
   1.461 +		pop	di
   1.462 +		ifndef	NO386
   1.463 +		add	eax,3
   1.464 +		and	al,0FCh
   1.465 +		add	[di+6],eax		; m->size += m->chunk_size
   1.466 +		or	eax,eax
   1.467 +		jnz	@@next
   1.468 +		else
   1.469 +		mov	cx,ax
   1.470 +		or	cx,dx
   1.471 +		add	ax,3
   1.472 +		adc	dx,0
   1.473 +		and	al,0FCh
   1.474 +		add	[di+6],ax		; m->size += m->chunk_size
   1.475 +		adc	[di+8],dx
   1.476 +		inc	cx
   1.477 +		loop	@@next
   1.478 +		endif
   1.479 +                mov	[di+28],si		; m->state
   1.480 +		push	di
   1.481 +                call	[word di+26]		; m->next_chunk()
   1.482 +		pop	di
   1.483 +@@alreadydone:
   1.484 +                push	ax
   1.485 +image_done:
   1.486 +                pop	ax
   1.487 +                pop	di si bp
   1.488 +		ret
   1.489 +
   1.490 +        endp    _open_image
   1.491 +
   1.492 +
   1.493 +;***************************************************************
   1.494 +;int read_image(struct image_himem *m, void* data, int sz);
   1.495 +;***************************************************************
   1.496 +        global  _read_image:near
   1.497 +        proc    _read_image near
   1.498 +
   1.499 +		arg	m	:word,	\
   1.500 +			data	:word,	\
   1.501 +			sz	:word	= PARAM_SIZE
   1.502 +
   1.503 +		push	bp
   1.504 +		mov	bp,sp
   1.505 +		push	si di
   1.506 +		ifndef	NO386
   1.507 +		push	0		; return value
   1.508 +		else
   1.509 +		xor	ax,ax
   1.510 +		push	ax
   1.511 +		endif
   1.512 +		mov	di,[m]
   1.513 +@@loop:
   1.514 +		mov	ax,[word sz]
   1.515 +		mov	cx,[di+22]	; m->chunk_size
   1.516 +		cmp	ax,cx
   1.517 +		jb	@@szok
   1.518 +		cmp	[word di+24],0	; hi m->chunk_size
   1.519 +		jne	@@szok
   1.520 +		xchg	ax,cx
   1.521 +@@szok:
   1.522 +		push	ax
   1.523 +		push	[word data]
   1.524 +		push	[word di]
   1.525 +		call	_read
   1.526 +		pop	cx
   1.527 +		pop	bx
   1.528 +		add	bx,ax
   1.529 +		pop	cx
   1.530 +		xor	cx,cx
   1.531 +		sub	[di+22],ax
   1.532 +		sbb	[di+24],cx
   1.533 +@@fill:
   1.534 +		test	al,3
   1.535 +		je	@@filled
   1.536 +		mov	[bx],cl
   1.537 +		inc	bx
   1.538 +		inc	ax
   1.539 +		jmp	@@fill
   1.540 +@@filled:
   1.541 +		add	[bp-4-2],ax
   1.542 +		add	[word data],ax
   1.543 +		sub	[word sz],ax
   1.544 +		jz	image_done
   1.545 +		mov	cx,[di+22]		; lo m->chunk_size
   1.546 +		or	cx,[di+24]		; hi m->chunk_size
   1.547 +		jnz	image_done
   1.548 +                or	cx,[di+26]		; m->next_chunk
   1.549 +		jz	image_done
   1.550 +		push	di
   1.551 +                call	cx			; m->next_chunk()
   1.552 +		pop	di
   1.553 +		mov	cx,[di+22]		; lo m->chunk_size
   1.554 +		or	cx,[di+24]		; hi m->chunk_size
   1.555 +		jz	image_done
   1.556 +		jmp	@@loop
   1.557 +
   1.558 +        endp    _read_image
   1.559 +
   1.560 +
   1.561 +;***************************************************************
   1.562 +;unsigned long strtol(const char *s);
   1.563 +;***************************************************************
   1.564 +        global  _strtol:near
   1.565 +        proc    _strtol near
   1.566 +
   1.567 +;TODO NO386
   1.568 +		ifndef	NO386
   1.569 +		pop	ax			;caller return address
   1.570 +                pop	cx			; s
   1.571 +		push	cx
   1.572 +		push	ax
   1.573 +		xor	ebx,ebx
   1.574 +		jcxz	@@end
   1.575 +		push	si
   1.576 +		mov	si,cx
   1.577 +		xor	ecx,ecx
   1.578 +		xor	eax,eax
   1.579 +		mov	cl,10			; radix
   1.580 +		lodsb
   1.581 +		cmp	al,'+'
   1.582 +		je	@@radixskip
   1.583 +		cmp	al,'-'
   1.584 +		clc
   1.585 +		jne	@@radixkeep
   1.586 +		stc
   1.587 +@@radixskip:
   1.588 +		lodsb
   1.589 +@@radixkeep:
   1.590 +		pushf
   1.591 +		cmp	al,'0'
   1.592 +		jne	@@radixok
   1.593 +		mov	cl,8
   1.594 +		lodsb
   1.595 +		mov	dl,20h
   1.596 +		or	dl,al
   1.597 +		cmp	dl,'x'
   1.598 +		jne	@@radixok
   1.599 +		mov	cl,16
   1.600 +@@strtollp:
   1.601 +		lodsb
   1.602 +@@radixok:
   1.603 +		sub	al,'0'
   1.604 +		jb	@@endstrtol
   1.605 +		cmp	al,9
   1.606 +		jbe	@@digitok
   1.607 +		or	al,20h
   1.608 +		cmp	al,'a'-'0'
   1.609 +		jb	@@endstrtol
   1.610 +		sub	al,'a'-'0'-10
   1.611 +@@digitok:
   1.612 +		cmp	al,cl
   1.613 +		jae	@@endstrtol
   1.614 +		xchg	eax,ebx
   1.615 +		mul	ecx
   1.616 +		add	eax,ebx
   1.617 +		xchg	eax,ebx
   1.618 +		jmp	@@strtollp
   1.619 +@@endstrtol:
   1.620 +		mov	cl,10
   1.621 +		cmp	al,'k'-'a'+10
   1.622 +		je	@@shift
   1.623 +		mov	cl,20
   1.624 +		cmp	al,'m'-'a'+10
   1.625 +		je	@@shift
   1.626 +		mov	cl,30
   1.627 +		cmp	al,'g'-'a'+10
   1.628 +		jne	@@noshift
   1.629 +@@shift:
   1.630 +		shl	ebx,cl
   1.631 +@@noshift:
   1.632 +		popf
   1.633 +		jnc	@@end
   1.634 +		neg	ebx
   1.635 +@@end:
   1.636 +		push	ebx
   1.637 +		pop	ax
   1.638 +		pop	dx
   1.639 +popsiret:
   1.640 +		pop	si
   1.641 +		else
   1.642 +		pop	ax			;caller return address
   1.643 +                pop	cx			; s
   1.644 +		push	cx
   1.645 +		push	ax
   1.646 +		push	si
   1.647 +		push	di
   1.648 +		xor	ax,ax
   1.649 +		cwd
   1.650 +		xchg	ax,di
   1.651 +		jcxz	@@end
   1.652 +		mov	si,cx
   1.653 +		mov	cx,10			; radix
   1.654 +		lodsb
   1.655 +		cmp	al,'+'
   1.656 +		je	@@radixskip
   1.657 +		cmp	al,'-'
   1.658 +		clc
   1.659 +		jne	@@radixkeep
   1.660 +		stc
   1.661 +@@radixskip:
   1.662 +		lodsb
   1.663 +@@radixkeep:
   1.664 +		pushf
   1.665 +		cmp	al,'0'
   1.666 +		jne	@@radixok
   1.667 +		mov	cl,8
   1.668 +		lodsb
   1.669 +		mov	ah,20h
   1.670 +		or	ah,al
   1.671 +		cmp	ah,'x'
   1.672 +		jne	@@radixok
   1.673 +		mov	cl,16
   1.674 +@@strtollp:
   1.675 +		lodsb
   1.676 +@@radixok:
   1.677 +		sub	al,'0'
   1.678 +		jb	@@endstrtol
   1.679 +		cmp	al,9
   1.680 +		jbe	@@digitok
   1.681 +		or	al,20h
   1.682 +		cmp	al,'a'-'0'
   1.683 +		jb	@@endstrtol
   1.684 +		sub	al,'a'-'0'-10
   1.685 +@@digitok:
   1.686 +		cmp	al,cl
   1.687 +		jae	@@endstrtol
   1.688 +
   1.689 +		push	ax
   1.690 +		push	si
   1.691 +		push	dx
   1.692 +		xchg	ax,di
   1.693 +		mul	cx
   1.694 +		xchg	ax,di
   1.695 +		xchg	ax,dx
   1.696 +		xchg	ax,si
   1.697 +		pop	ax
   1.698 +		mul	cx
   1.699 +		add	ax,si
   1.700 +		pop	si
   1.701 +		xchg	ax,dx
   1.702 +		pop	ax
   1.703 +		mov	ah,0
   1.704 +		add	di,ax
   1.705 +		adc	dx,0
   1.706 +
   1.707 +		jmp	@@strtollp
   1.708 +@@endstrtol:
   1.709 +		mov	cl,10
   1.710 +		cmp	al,'k'-'a'+10
   1.711 +		je	@@shift
   1.712 +		mov	cl,20
   1.713 +		cmp	al,'m'-'a'+10
   1.714 +		je	@@shift
   1.715 +		mov	cl,30
   1.716 +		cmp	al,'g'-'a'+10
   1.717 +		jne	@@noshift
   1.718 +@@shift:
   1.719 +		rcl	di,1
   1.720 +		shl	dx,1
   1.721 +		loop	@@shift
   1.722 +@@noshift:
   1.723 +		popf
   1.724 +		jnc	@@end
   1.725 +		not	dx
   1.726 +		neg	di
   1.727 +		jne	@@end
   1.728 +		inc	dx
   1.729 +@@end:
   1.730 +		xchg	ax,di
   1.731 +		pop	di
   1.732 +popsiret:
   1.733 +		pop	si
   1.734 +		endif
   1.735 +		ret
   1.736 +
   1.737 +        endp    _strtol
   1.738 +
   1.739 +
   1.740 +;***************************************************************
   1.741 +;>void sort(unsigned long  *base:BX!, size_t nel:CX)
   1.742 +;NO386 safe: only used by VCPI
   1.743 +;***************************************************************
   1.744 +        global  _sort:near
   1.745 +        proc    _sort near
   1.746 +
   1.747 +		pop	ax			;caller return address
   1.748 +                pop	bx			; base
   1.749 +		pop	cx			; nel
   1.750 +		push	cx
   1.751 +		push	bx
   1.752 +		push	ax
   1.753 +        global  sort:near
   1.754 +sort:
   1.755 +	ifndef	fastsort
   1.756 +;  bubble sort
   1.757 +		push	si
   1.758 +		cmp	cx,2
   1.759 +		jl	popsiret
   1.760 +		shl	cx,2
   1.761 +@@loop:
   1.762 +		xor	ax,ax
   1.763 +		jcxz	popsiret
   1.764 +		mov	si,4
   1.765 +@@next:
   1.766 +		mov	edx,[bx+si-4]
   1.767 +		cmp	edx,[bx+si]
   1.768 +		jbe	@@ok
   1.769 +		xchg	edx,[bx+si]
   1.770 +		mov	[bx+si-4],edx
   1.771 +		mov	ax,si
   1.772 +@@ok:
   1.773 +		add	si,4
   1.774 +		cmp	si,cx
   1.775 +		jb	@@next
   1.776 +		xchg	ax,cx
   1.777 +		jmp	@@loop
   1.778 +	else
   1.779 +;  shell sort (c) uclibc GPL
   1.780 +		push	si di
   1.781 +; {
   1.782 +;>	size_t wgap:SI;
   1.783 +;
   1.784 +;	if (nel > 1) {
   1.785 +		cmp	cx,1
   1.786 +		jbe	@@end
   1.787 +;		wgap = 0;
   1.788 +		xor	ax,ax
   1.789 +;		do {
   1.790 +@@wgaplp:
   1.791 +		mov	si,ax
   1.792 +;			wgap = 3 * wgap + 1;
   1.793 +		mov	dx,3
   1.794 +		mul	dx
   1.795 +		inc	ax
   1.796 +;		} while (wgap < (nel-1)/3);
   1.797 +		cmp	ax,cx
   1.798 +		jb	@@wgaplp
   1.799 +;		/* From the above, we know that either wgap == 1 < nel or */
   1.800 +;		/* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap <  nel. */
   1.801 +;		wgap *= 4;			/* So this can not overflow if wnel doesn't. */
   1.802 +		shl	si,2
   1.803 +;		nel *= 4;			/* Convert nel to 'wnel' */
   1.804 +		shl	cx,2
   1.805 +;		do {
   1.806 +@@lp1:
   1.807 +;>	                size_t i:DI;
   1.808 +;			i = wgap;
   1.809 +		mov	di,si
   1.810 +;			do {
   1.811 +@@lp2:
   1.812 +;>	                	size_t j:DX;
   1.813 +;				j = i;
   1.814 +		mov	dx,di
   1.815 +;				do {
   1.816 +@@lp3:
   1.817 +;>					register char *a:BX!;
   1.818 +;
   1.819 +;					j -= wgap;
   1.820 +		sub	dx,si
   1.821 +;					a = j + ((char *)base);
   1.822 +		push	bx
   1.823 +		add	bx,dx
   1.824 +;					if (cmp(a, a + wgap) <= 0) {
   1.825 +		mov	eax,[bx]
   1.826 +		cmp	eax,[bx+si]
   1.827 +		jbe	@@brk3
   1.828 +;						break;
   1.829 +;					}
   1.830 +		xchg	eax,[bx+si]
   1.831 +		mov	[bx],eax
   1.832 +;					swap(a, a + wgap);
   1.833 +		pop	bx
   1.834 +;				} while (j >= wgap);
   1.835 +		cmp	dx,si
   1.836 +		jae	@@lp3
   1.837 +		push	bx
   1.838 +@@brk3:
   1.839 +		pop	bx
   1.840 +;				i += 4;
   1.841 +		add	di,4
   1.842 +;			} while (i < nel);
   1.843 +		cmp	di,cx
   1.844 +		jb	@@lp2
   1.845 +;			wgap = (wgap - 4)/3;
   1.846 +		sub	si,4
   1.847 +		xchg	ax,si
   1.848 +		cwd
   1.849 +		mov	si,3
   1.850 +		div	si	; kill dx
   1.851 +		xchg	ax,si
   1.852 +;		} while (wgap);
   1.853 +		or	si,si
   1.854 +		jnz	@@lp1
   1.855 +@@end:
   1.856 +;	}
   1.857 +;}
   1.858 +		pop	di si
   1.859 +		ret
   1.860 +endif
   1.861 +
   1.862 +        endp    _sort
   1.863 +
   1.864 +
   1.865 +;***************************************************************
   1.866 +;void* malloc(unsigned sz);
   1.867 +;***************************************************************
   1.868 +        global  _malloc:near
   1.869 +        proc    _malloc near
   1.870 +
   1.871 +		pop	ax			;caller return address
   1.872 +                pop	cx			; sz
   1.873 +		push	cx
   1.874 +		push	ax
   1.875 +        global  malloc:near			; malloc(cx)
   1.876 +malloc:
   1.877 +		mov	ax,[_heap_top]
   1.878 +		mov	bx,sp
   1.879 +		sub	bh,14h			; MIN_STACK=_1k+PAGE_SIZE
   1.880 +		sub	bx,cx
   1.881 +		jb	@@outofmem
   1.882 +		cmp	bx,ax
   1.883 +		jb	@@outofmem
   1.884 +		add	[_heap_top],cx		; _BEG has zero'd heap
   1.885 +		;mov	bx,ax
   1.886 +@@zalloc:
   1.887 +		;mov	[byte bx],0
   1.888 +		;inc	bx			; ZF=0
   1.889 +		;loop	@@zalloc
   1.890 +		ret
   1.891 +@@outofmem:
   1.892 +		mov	bx,offset msg_malloc
   1.893 +		call	puts
   1.894 +		xor	ax,ax			; ZF=1
   1.895 +		ret
   1.896 +
   1.897 +        endp    _malloc
   1.898 +
   1.899 +
   1.900 +		ifdef	NO386
   1.901 +;***************************************************************
   1.902 +;u16 topseg();
   1.903 +;***************************************************************
   1.904 +        global  _topseg:near
   1.905 +        proc    _topseg near
   1.906 +
   1.907 +		int	12h
   1.908 +		jnc	@@max640k
   1.909 +		mov	ax,640			; 9000
   1.910 +@@max640k:
   1.911 +		sub	al,040h
   1.912 +		and	al,0C0h
   1.913 +		mov	cl,6
   1.914 +		shl	ax,cl
   1.915 +		ret
   1.916 +
   1.917 +        endp    _topseg
   1.918 +		endif
   1.919 +
   1.920 +
   1.921 +        ends    _TEXT
   1.922 +
   1.923 +        end
   1.924 +
   1.925 +;###### END OF FILE ############################################