wok 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 10d3d9504ec6
children eaad6c4ccbaa
files linld/receipt linld/stuff/src/!COMPILE.BAT linld/stuff/src/!COMPILEX.BAT linld/stuff/src/COMMON.H linld/stuff/src/CRTL.ASM linld/stuff/src/CRTL.H linld/stuff/src/CRTLX.ASM linld/stuff/src/CRTLX.H linld/stuff/src/HIMEM.CPP linld/stuff/src/JUMP.ASM linld/stuff/src/LINLD.CPP linld/stuff/src/LOAD.CPP linld/stuff/src/MEMCPY32.ASM linld/stuff/src/TAZBOOT.CPP linld/stuff/src/VCPI.ASM linld/stuff/src/XMM.ASM linld/stuff/src/_BEG.ASM
line diff
     1.1 --- a/linld/receipt	Thu Dec 01 21:07:54 2016 +0200
     1.2 +++ b/linld/receipt	Fri Dec 02 12:37:59 2016 +0100
     1.3 @@ -36,8 +36,8 @@
     1.4  	cp TAZBOOT/TAZBOOT.COM tazboot.com
     1.5  	objdump -D -b binary -mi386 -Maddr16,data16 --adjust-vma=0x100 \
     1.6  		linld.com > linld.lst
     1.7 -	upx linld.com
     1.8 -	upx tazboot.com
     1.9 +	upx --8086 linld.com
    1.10 +	upx --8086 tazboot.com
    1.11  	cc -o tobzimage.o -Wa,-algms=tobzimage.lst -c $stuff/tobzimage.S
    1.12  	objcopy -O binary tobzimage.o tobzimage.bin
    1.13  	cp $stuff/tobzimage .
     2.1 --- a/linld/stuff/src/!COMPILE.BAT	Thu Dec 01 21:07:54 2016 +0200
     2.2 +++ b/linld/stuff/src/!COMPILE.BAT	Fri Dec 02 12:37:59 2016 +0100
     2.3 @@ -1,9 +1,9 @@
     2.4  path ..\BC31;%PATH%
     2.5  call !clean.bat
     2.6 -tasm > help.log
     2.7 -bcc > help2.log
     2.8 -tlink > help3.log
     2.9 -tasm /l /m *.asm > asm.log
    2.10 +tasm /h > helptasm.log
    2.11 +bcc > helpbcc.log
    2.12 +tlink > helptlink.log
    2.13 +tasm /la /m *.asm > asm.log
    2.14  rem @pause
    2.15  bcc @bccopt.opt -S -mt *.cpp
    2.16  tasm /l /m load.asm
     3.1 --- a/linld/stuff/src/!COMPILEX.BAT	Thu Dec 01 21:07:54 2016 +0200
     3.2 +++ b/linld/stuff/src/!COMPILEX.BAT	Fri Dec 02 12:37:59 2016 +0100
     3.3 @@ -1,6 +1,6 @@
     3.4  path ..\BC31;%PATH%
     3.5  call !clean.bat
     3.6 -tasm /l /m /dNO386 *.asm > asm.log
     3.7 +tasm /la /m /dNO386 *.asm > asm.log
     3.8  rem @pause
     3.9  bcc @bccopt.opt -S -mt *.cpp
    3.10  tasm /l /m load.asm
     4.1 --- a/linld/stuff/src/COMMON.H	Thu Dec 01 21:07:54 2016 +0200
     4.2 +++ b/linld/stuff/src/COMMON.H	Fri Dec 02 12:37:59 2016 +0100
     4.3 @@ -46,6 +46,7 @@
     4.4      u32 chunk_size;
     4.5      void (*next_chunk)(struct image_himem *);
     4.6      u16 state;
     4.7 +    u16 fd2close;
     4.8  } pm, initrd;
     4.9  
    4.10  extern char vcpi;
    4.11 @@ -55,9 +56,10 @@
    4.12  extern u16 root_dev;
    4.13  extern u16 vid_mode;
    4.14  // External asm helpers
    4.15 -extern "C" void memcpy32(u16,u32, u16,u32, u32);
    4.16 +extern "C" void memcpy32(u32, u16,u32, u32);
    4.17 +extern "C" void rmcpy(void* rmbuf, u16 rmsize);
    4.18  extern "C" void set_sregs_jump_seg_ofs(u32 csip, u32 sssp);
    4.19 -extern "C" u32 xmm_alloc(u32 size);
    4.20 +extern "C" void xmm_alloc(struct image_himem *m);
    4.21  extern u32 topmem;
    4.22  extern "C" u32 memtopz();
    4.23  extern "C" u32 memtop();
    4.24 @@ -65,7 +67,7 @@
    4.25  extern "C" int get_vcpi_interface();
    4.26  extern "C" char* prepare_vcpi(void *pagebuf);
    4.27  //extern "C" int call_pm_routine(void* f);
    4.28 -extern "C" void memcpy_vcpi(u32 dstofs,u16 srcseg,u16 srcofs);
    4.29 +extern "C" void memcpy_vcpi(u32 dstofs,u16 srcseg,u32 srcofs);
    4.30  extern "C" void vm2rm();
    4.31  extern "C" void hook_int15_88();
    4.32  
     5.1 --- a/linld/stuff/src/CRTL.ASM	Thu Dec 01 21:07:54 2016 +0200
     5.2 +++ b/linld/stuff/src/CRTL.ASM	Fri Dec 02 12:37:59 2016 +0100
     5.3 @@ -13,8 +13,7 @@
     5.4          segment _DATA byte public use16 'DATA'
     5.5  
     5.6  msg_hang	db      "High mem corrupted - not exiting to DOS",0
     5.7 -        global  _vcpi_alloc_err:byte
     5.8 -_vcpi_alloc_err	db	"vcpi "
     5.9 +vcpi_alloc_err	db	"vcpi "
    5.10  msg_malloc      db      "malloc() failure",0
    5.11  msg_crlf	db	13,10,0
    5.12  
    5.13 @@ -34,6 +33,104 @@
    5.14          segment _TEXT byte public use16 'CODE'
    5.15  
    5.16  ;***************************************************************
    5.17 +;char* strcpy(const char* a, const char* b);
    5.18 +;***************************************************************
    5.19 +        global  _strcpy:near
    5.20 +        proc    _strcpy near
    5.21 +
    5.22 +		mov	dl,0
    5.23 +cat:
    5.24 +		pop	ax			;caller return address
    5.25 +                pop	cx			; a
    5.26 +                pop	bx			; b
    5.27 +                push	bx
    5.28 +                push	cx
    5.29 +                push	ax
    5.30 +                push	si
    5.31 +                mov	si,cx
    5.32 +		shr	dl,1
    5.33 +		jnc	@@nocat
    5.34 +@@catlp:
    5.35 +		lodsb
    5.36 +		cmp	al,0
    5.37 +                jne	@@catlp
    5.38 +		dec	si
    5.39 +		shr	dl,1
    5.40 +		jnc	@@nocat
    5.41 +		cmp	cx,si
    5.42 +		jz	@@nocat
    5.43 +		mov	[word si],20h
    5.44 +		inc	si
    5.45 +@@nocat:
    5.46 +                sub	bx,si
    5.47 +@@cpylp:
    5.48 +                mov	al,[bx+si]
    5.49 +                mov	[si],al
    5.50 +                inc	si
    5.51 +		cmp	al,0
    5.52 +                jne	@@cpylp
    5.53 +		mov	ax,cx
    5.54 +                pop	si
    5.55 +                ret
    5.56 +
    5.57 +        endp    _strcpy
    5.58 +
    5.59 +
    5.60 +;***************************************************************
    5.61 +;char* strcat(const char* a,const char* b);
    5.62 +;***************************************************************
    5.63 +        global  _strcat:near
    5.64 +        proc    _strcat near
    5.65 +
    5.66 +		mov	dl,1
    5.67 +                jmp	cat
    5.68 +
    5.69 +        endp    _strcat
    5.70 +
    5.71 +
    5.72 +;***************************************************************
    5.73 +;char* strcatb(const char* a,const char* b);
    5.74 +;***************************************************************
    5.75 +        global  _strcatb:near
    5.76 +        proc    _strcatb near
    5.77 +
    5.78 +		mov	dl,3
    5.79 +                jmp	cat
    5.80 +
    5.81 +        endp    _strcatb
    5.82 +
    5.83 +
    5.84 +;***************************************************************
    5.85 +;void* malloc(unsigned sz);
    5.86 +;***************************************************************
    5.87 +        global  _malloc:near
    5.88 +        proc    _malloc near
    5.89 +
    5.90 +		pop	ax			;caller return address
    5.91 +                pop	cx			; sz
    5.92 +		push	cx
    5.93 +		push	ax
    5.94 +        global  malloc:near			; malloc(cx)
    5.95 +malloc:
    5.96 +		mov	ax,[_heap_top]
    5.97 +		mov	bx,offset msg_malloc
    5.98 +		mov	dx,-1400h		; MIN_STACK=_1k+PAGE_SIZE
    5.99 +		add	dx,sp
   5.100 +		sub	dx,ax			; can't overflow
   5.101 +		cmp	dx,cx
   5.102 +		jb	puts
   5.103 +		add	[_heap_top],cx		; _BEG has zero'd heap
   5.104 +		;mov	bx,ax
   5.105 +@@zalloc:
   5.106 +		;mov	[byte bx],0
   5.107 +		;inc	bx			; ZF=0
   5.108 +		;loop	@@zalloc
   5.109 +		ret
   5.110 +
   5.111 +        endp    _malloc
   5.112 +
   5.113 +
   5.114 +;***************************************************************
   5.115  ;void puts(const char* s):
   5.116  ;void putsz(const char* s):
   5.117  ;***************************************************************
   5.118 @@ -64,12 +161,32 @@
   5.119  		xchg	ax,cx
   5.120  		mov	bx,1
   5.121                  mov	ah,40h
   5.122 -		jmp	dos
   5.123 +                int	21h
   5.124 +		xor	ax,ax			; ZF=1	(for malloc failure)
   5.125 +		ret
   5.126  
   5.127          endp    _puts
   5.128  
   5.129  
   5.130  ;***************************************************************
   5.131 +;int fileattr(const char* name);
   5.132 +;***************************************************************
   5.133 +        global  _fileattr:near
   5.134 +        proc    _fileattr near
   5.135 +
   5.136 +		pop	ax			;caller return address
   5.137 +                pop	dx			; name
   5.138 +                push	dx
   5.139 +                push	ax
   5.140 +                mov	ax,4300h
   5.141 +                int	21h
   5.142 +		xchg	ax,cx
   5.143 +		jmp	chkc
   5.144 +
   5.145 +        endp    _fileattr
   5.146 +
   5.147 +
   5.148 +;***************************************************************
   5.149  ;int open(const char* name, int flags);
   5.150  ;***************************************************************
   5.151          global  _open:near
   5.152 @@ -87,15 +204,16 @@
   5.153                  mov	ah,3dh
   5.154  dos:
   5.155                  int	21h
   5.156 +chkc:
   5.157                  jnc	doret
   5.158  fail:
   5.159                  sbb	ax,ax			; ax=-1 CF
   5.160  		cwd
   5.161  doret:
   5.162  		ifndef	NO386
   5.163 -                push	dx
   5.164 -                push	ax
   5.165 -                pop	eax
   5.166 +		push	dx			; see next_chunk:lseek
   5.167 +		push	ax
   5.168 +		pop	eax
   5.169  		endif
   5.170                  ret
   5.171  
   5.172 @@ -170,7 +288,6 @@
   5.173  
   5.174  ;***************************************************************
   5.175  ;long lseek(int fd, long sz, int dir);
   5.176 -;long rewind(int fd);
   5.177  ;***************************************************************
   5.178          global  _lseek:near
   5.179          proc    _lseek near
   5.180 @@ -201,23 +318,6 @@
   5.181  		endif
   5.182  		jmp	dos
   5.183  
   5.184 -        global  _rewind:near
   5.185 -_rewind:
   5.186 -		pop	ax			;caller return address
   5.187 -                pop	bx			; fd
   5.188 -                push	bx
   5.189 -                push	ax
   5.190 -rewind:
   5.191 -		ifndef	NO386
   5.192 -		xor	ecx,ecx
   5.193 -		xor	dx,dx
   5.194 -		else
   5.195 -		xor	ax,ax
   5.196 -		xor	cx,cx
   5.197 -		cwd
   5.198 -		endif
   5.199 -		jmp	lseek
   5.200 -
   5.201          endp    _lseek
   5.202  
   5.203  
   5.204 @@ -290,7 +390,7 @@
   5.205          global  malloc_or_die:near		; malloc_or_die(cx)
   5.206  malloc_or_die:
   5.207  		call	malloc
   5.208 -		jz	_diez
   5.209 +		jz	_exit
   5.210  		ret
   5.211  
   5.212          endp    _malloc_or_die
   5.213 @@ -298,7 +398,7 @@
   5.214  
   5.215  ;***************************************************************
   5.216  ;int die(const char* msg);
   5.217 -;int diez();
   5.218 +;int exit();
   5.219  ;int abort();
   5.220  ;***************************************************************
   5.221          global  _die:near
   5.222 @@ -311,8 +411,8 @@
   5.223          global  die:near			; die(bx)
   5.224  die:
   5.225  		call	puts
   5.226 -        global  _diez:near
   5.227 -_diez:
   5.228 +        global  _exit:near
   5.229 +_exit:
   5.230  		mov	al,[_no_exit]
   5.231  		cmp	al,0
   5.232  		jne	@@hang
   5.233 @@ -333,6 +433,87 @@
   5.234  
   5.235  
   5.236  ;***************************************************************
   5.237 +;u32* malloc_bufv_or_die(struct image_himem *m);
   5.238 +;***************************************************************
   5.239 +        global  _malloc_bufv_or_die:near
   5.240 +        proc    _malloc_bufv_or_die near
   5.241 +
   5.242 +		pop	bx			;caller return address
   5.243 +		pop	ax
   5.244 +		push	ax
   5.245 +		push	bx
   5.246 +		push	si
   5.247 +		xchg	ax,si
   5.248 +		mov	ecx,[si+6]		; m->size
   5.249 +		dec	ecx
   5.250 +		shr	ecx,12
   5.251 +		inc	cx			; cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
   5.252 +		push	cx
   5.253 +		inc	cx			; cnt+1
   5.254 +		shl	cx,2			; bufv => vcpi => vm86
   5.255 +; our malloc zeroes allocated mem: bufv[cnt]=0;
   5.256 +; Allocate pages, storing addrs in addrbuf
   5.257 +		call	malloc_or_die
   5.258 +                pop	cx
   5.259 +		push	cx			; _sort:nel
   5.260 +		push	ax			; _sort:base
   5.261 +		mov	[si+18],ax		; m->bufv
   5.262 +		xchg	ax,bx
   5.263 +@@vcpi_alloc:
   5.264 +                xor     edx,edx
   5.265 +                mov     ax,0DE04h
   5.266 +                int     67h
   5.267 +		or	ah,ah
   5.268 +		jz	@@ok
   5.269 +		mov	bx,offset vcpi_alloc_err
   5.270 +		jmp	die
   5.271 +@@ok:
   5.272 +		mov	[bx],edx
   5.273 +		add	bx,4
   5.274 +		loop	@@vcpi_alloc
   5.275 +@@again:
   5.276 +		call	_sort
   5.277 +		extrn	_initrd
   5.278 +		cmp	si,offset _initrd
   5.279 +		jne	@@quit
   5.280 +		pop	ax
   5.281 +		pop	cx
   5.282 +		push	cx			; _sort:nel
   5.283 +		push	ax			; _sort:base = m->bufv
   5.284 +;again:
   5.285 +; for (i = cnt-1; i >= 0; i--) {
   5.286 +@@chkloop:
   5.287 +		mov	bx,cx
   5.288 +		dec	bx
   5.289 +;   if  (m->bufv[i] > m->fallback+i*_4k && m->bufv[i] < m->fallback+m->size) {
   5.290 +		shl	bx,2
   5.291 +		add	bx,ax			; m->bufv
   5.292 +		mov	edx,[bx]		; m->bufv[i]
   5.293 +		sub	edx,[si+2]		; m->fallback
   5.294 +		cmp	edx,[si+6]		; m->size
   5.295 +		jae	@@chknext
   5.296 +		shr	edx,12
   5.297 +		cmp	dx,cx
   5.298 +		jb	@@chknext
   5.299 +;     m->bufv[i] = vcpi_alloc_or_die();
   5.300 +;     sort(m->bufv,cnt);
   5.301 +;     goto again;
   5.302 +		mov	cx,1
   5.303 +		jmp	@@vcpi_alloc
   5.304 +;   }
   5.305 +; }
   5.306 +@@chknext:
   5.307 +		loop	@@chkloop
   5.308 +@@quit:
   5.309 +		pop	ax
   5.310 +		pop	cx
   5.311 +		pop	si
   5.312 +		ret
   5.313 +
   5.314 +        endp    _malloc_bufv_or_die
   5.315 +
   5.316 +
   5.317 +;***************************************************************
   5.318  ;void next_chunk(struct image_himem *m);
   5.319  ;***************************************************************
   5.320          proc    _next_chunk near
   5.321 @@ -341,7 +522,7 @@
   5.322  		pop	ax
   5.323  		push	ax
   5.324  		push	bx
   5.325 -		push	di
   5.326 +		push	si di
   5.327  		xchg	ax,di
   5.328  		mov	bx,[di]			; m->fd
   5.329  		call	close
   5.330 @@ -355,7 +536,6 @@
   5.331  		mov	bx,[di+28]		; m->state
   5.332  		cmp	al,[bx]			; ""
   5.333  		jz	@@end
   5.334 -		push	si
   5.335  		mov	si,bx
   5.336  @@scan:
   5.337  		lodsb
   5.338 @@ -373,9 +553,9 @@
   5.339  		xchg	ax,dx			; O_RDONLY
   5.340  		call	open
   5.341  		pop	[word si]		; restore string
   5.342 -		pop	si
   5.343  		jc	@@die
   5.344  		mov	[di],ax			; m->fd
   5.345 +		mov	[di+30],ax		; m->fd2close
   5.346  		mov	dx,2			; SEEK_END
   5.347  		xchg	ax,bx
   5.348  		ifndef	NO386
   5.349 @@ -391,21 +571,26 @@
   5.350  		mov	bx,[di]			; m->fd
   5.351  		ifndef	NO386
   5.352  		push	eax
   5.353 -		call	rewind
   5.354 +		xor	ecx,ecx
   5.355 +		xor	dx,dx
   5.356 +		call	lseek			; rewind
   5.357  		pop	eax
   5.358  @@end:
   5.359  		mov	[di+22],eax		; m->chunk_size
   5.360  		else
   5.361  		push	ax
   5.362  		push	dx
   5.363 -		call	rewind
   5.364 +		xor	ax,ax
   5.365 +		xor	cx,cx
   5.366 +		cwd
   5.367 +		call	lseek			; rewind
   5.368  		pop	dx
   5.369  		pop	ax
   5.370  @@end:
   5.371  		mov	[di+22],ax		; m->chunk_size
   5.372  		mov	[di+24],dx
   5.373  		endif
   5.374 -		pop	di
   5.375 +		pop	di si
   5.376  		ret
   5.377  
   5.378          endp    _next_chunk
   5.379 @@ -424,6 +609,7 @@
   5.380  ;22    u32 chunk_size;
   5.381  ;26    void (*next_chunk)(struct image_himem *);
   5.382  ;28    u16 state;
   5.383 +;30    u16 fd2close;
   5.384  ;};
   5.385  ;***************************************************************
   5.386          global  _open_image:near
   5.387 @@ -470,7 +656,7 @@
   5.388  		and	al,0FCh
   5.389  		add	[di+6],ax		; m->size += m->chunk_size
   5.390  		adc	[di+8],dx
   5.391 -		inc	cx
   5.392 +		inc	cx			; jcxnz
   5.393  		loop	@@next
   5.394  		endif
   5.395                  mov	[di+28],si		; m->state
   5.396 @@ -508,49 +694,76 @@
   5.397  		endif
   5.398  		mov	di,[m]
   5.399  @@loop:
   5.400 -		mov	ax,[word sz]
   5.401 -		mov	cx,[di+22]	; m->chunk_size
   5.402 -		cmp	ax,cx
   5.403 +		ifndef	NO386
   5.404 +		xor	ecx,ecx
   5.405 +		mov	cx,[word sz]
   5.406 +@@chksz:
   5.407 +		mov	eax,[di+22]	; m->chunk_size
   5.408 +		cmp	ecx,eax
   5.409 +		jb	@@szok
   5.410 +		xchg	eax,ecx
   5.411 +		else
   5.412 +		mov	cx,[word sz]
   5.413 +@@chksz:
   5.414 +		mov	ax,[di+22]	; lo m->chunk_size
   5.415 +		cmp	cx,ax
   5.416  		jb	@@szok
   5.417  		cmp	[word di+24],0	; hi m->chunk_size
   5.418  		jne	@@szok
   5.419  		xchg	ax,cx
   5.420 +		endif
   5.421  @@szok:
   5.422 -		push	ax
   5.423 +		jcxz	image_done
   5.424 +		push	cx
   5.425  		push	[word data]
   5.426  		push	[word di]
   5.427  		call	_read
   5.428 -		pop	cx
   5.429 +		pop	dx
   5.430  		pop	bx
   5.431 +		pop	dx
   5.432 +		jc	image_done
   5.433  		add	bx,ax
   5.434 -		pop	cx
   5.435  		xor	cx,cx
   5.436 +		ifndef	NO386
   5.437 +		cwde				; ax < 8000h
   5.438 +		cwd
   5.439 +		sub	[di+22],eax
   5.440 +		else
   5.441 +		cwd				; ax < 8000h
   5.442  		sub	[di+22],ax
   5.443 -		sbb	[di+24],cx
   5.444 +		sbb	[di+24],dx
   5.445 +		jnz	@@fill
   5.446 +		cmp	[di+22],dx
   5.447 +		endif
   5.448 +		jnz	@@fill
   5.449 +		dec	cx
   5.450  @@fill:
   5.451  		test	al,3
   5.452  		je	@@filled
   5.453 -		mov	[bx],cl
   5.454 +		mov	[bx],dl
   5.455  		inc	bx
   5.456  		inc	ax
   5.457  		jmp	@@fill
   5.458  @@filled:
   5.459 +		ifndef	NO386
   5.460 +		sub	[di+10],eax		; m->remaining
   5.461 +		else
   5.462 +		sub	[di+10],ax		; m->remaining
   5.463 +		sbb	[di+12],dx
   5.464 +		endif
   5.465  		add	[bp-4-2],ax
   5.466  		add	[word data],ax
   5.467  		sub	[word sz],ax
   5.468 -		jz	image_done
   5.469 -		mov	cx,[di+22]		; lo m->chunk_size
   5.470 -		or	cx,[di+24]		; hi m->chunk_size
   5.471 -		jnz	image_done
   5.472 -                or	cx,[di+26]		; m->next_chunk
   5.473 -		jz	image_done
   5.474 +		pushf
   5.475 +                and	cx,[di+26]		; m->next_chunk
   5.476 +		jz	@@same_chunk
   5.477  		push	di
   5.478                  call	cx			; m->next_chunk()
   5.479  		pop	di
   5.480 -		mov	cx,[di+22]		; lo m->chunk_size
   5.481 -		or	cx,[di+24]		; hi m->chunk_size
   5.482 -		jz	image_done
   5.483 -		jmp	@@loop
   5.484 +@@same_chunk:
   5.485 +		popf
   5.486 +		jnz	@@loop
   5.487 +		jmp	image_done
   5.488  
   5.489          endp    _read_image
   5.490  
   5.491 @@ -561,20 +774,35 @@
   5.492          global  _strtol:near
   5.493          proc    _strtol near
   5.494  
   5.495 -;TODO NO386
   5.496  		ifndef	NO386
   5.497  		pop	ax			;caller return address
   5.498                  pop	cx			; s
   5.499  		push	cx
   5.500  		push	ax
   5.501  		xor	ebx,ebx
   5.502 -		jcxz	@@end
   5.503 +		jcxz	@@jncend
   5.504  		push	si
   5.505  		mov	si,cx
   5.506  		xor	ecx,ecx
   5.507  		xor	eax,eax
   5.508 -		mov	cl,10			; radix
   5.509  		lodsb
   5.510 +		mov	dl,20h
   5.511 +		or	dl,al
   5.512 +		cmp	dl,'n'			; vga=normal
   5.513 +		je	@@vga
   5.514 +		dec	cx
   5.515 +		cmp	dl,'e'			; vga=extended
   5.516 +		je	@@vga
   5.517 +		dec	cx
   5.518 +		cmp	dl,'a'			; vga=ask
   5.519 +		jne	@@notvga
   5.520 +@@vga:
   5.521 +		dec	cx
   5.522 +		xchg	ax,cx
   5.523 +		cwd
   5.524 +		jmp	popsiret
   5.525 +@@notvga:
   5.526 +		mov	cx,10			; radix
   5.527  		cmp	al,'+'
   5.528  		je	@@radixskip
   5.529  		cmp	al,'-'
   5.530 @@ -627,6 +855,7 @@
   5.531  		shl	ebx,cl
   5.532  @@noshift:
   5.533  		popf
   5.534 +@@jncend:
   5.535  		jnc	@@end
   5.536  		neg	ebx
   5.537  @@end:
   5.538 @@ -645,10 +874,28 @@
   5.539  		xor	ax,ax
   5.540  		cwd
   5.541  		xchg	ax,di
   5.542 -		jcxz	@@end
   5.543 +		jcxz	@@goend
   5.544  		mov	si,cx
   5.545 +		lodsb
   5.546 +		mov	dl,20h
   5.547 +		or	dl,al
   5.548 +		mov	cx,-1
   5.549 +		cmp	dl,'n'			; vga=normal
   5.550 +		je	@@vga
   5.551 +		dec	cx
   5.552 +		cmp	dl,'e'			; vga=extended
   5.553 +		je	@@vga
   5.554 +		dec	cx
   5.555 +		cmp	dl,'a'			; vga=ask
   5.556 +		jne	@@notvga
   5.557 +@@vga:
   5.558 +		xchg	ax,cx
   5.559 +		cwd
   5.560 +		jmp	popsiret
   5.561 +@@goend:
   5.562 +		jmp	@@end
   5.563 +@@notvga:
   5.564  		mov	cx,10			; radix
   5.565 -		lodsb
   5.566  		cmp	al,'+'
   5.567  		je	@@radixskip
   5.568  		cmp	al,'-'
   5.569 @@ -752,13 +999,12 @@
   5.570  	ifndef	fastsort
   5.571  ;  bubble sort
   5.572  		push	si
   5.573 -		cmp	cx,2
   5.574 -		jl	popsiret
   5.575  		shl	cx,2
   5.576  @@loop:
   5.577  		xor	ax,ax
   5.578 -		jcxz	popsiret
   5.579  		mov	si,4
   5.580 +		cmp	cx,si
   5.581 +		jbe	popsiret
   5.582  @@next:
   5.583  		mov	edx,[bx+si-4]
   5.584  		cmp	edx,[bx+si]
   5.585 @@ -859,41 +1105,6 @@
   5.586          endp    _sort
   5.587  
   5.588  
   5.589 -;***************************************************************
   5.590 -;void* malloc(unsigned sz);
   5.591 -;***************************************************************
   5.592 -        global  _malloc:near
   5.593 -        proc    _malloc near
   5.594 -
   5.595 -		pop	ax			;caller return address
   5.596 -                pop	cx			; sz
   5.597 -		push	cx
   5.598 -		push	ax
   5.599 -        global  malloc:near			; malloc(cx)
   5.600 -malloc:
   5.601 -		mov	ax,[_heap_top]
   5.602 -		mov	bx,sp
   5.603 -		sub	bh,14h			; MIN_STACK=_1k+PAGE_SIZE
   5.604 -		sub	bx,cx
   5.605 -		jb	@@outofmem
   5.606 -		cmp	bx,ax
   5.607 -		jb	@@outofmem
   5.608 -		add	[_heap_top],cx		; _BEG has zero'd heap
   5.609 -		;mov	bx,ax
   5.610 -@@zalloc:
   5.611 -		;mov	[byte bx],0
   5.612 -		;inc	bx			; ZF=0
   5.613 -		;loop	@@zalloc
   5.614 -		ret
   5.615 -@@outofmem:
   5.616 -		mov	bx,offset msg_malloc
   5.617 -		call	puts
   5.618 -		xor	ax,ax			; ZF=1
   5.619 -		ret
   5.620 -
   5.621 -        endp    _malloc
   5.622 -
   5.623 -
   5.624  		ifdef	NO386
   5.625  ;***************************************************************
   5.626  ;u16 topseg();
   5.627 @@ -905,7 +1116,7 @@
   5.628  		jnc	@@max640k
   5.629  		mov	ax,640			; 9000
   5.630  @@max640k:
   5.631 -		sub	al,040h
   5.632 +		sub	ax,028h
   5.633  		and	al,0C0h
   5.634  		mov	cl,6
   5.635  		shl	ax,cl
   5.636 @@ -914,6 +1125,41 @@
   5.637          endp    _topseg
   5.638  		endif
   5.639  
   5.640 +;***************************************************************
   5.641 +;void rmcpy(void* rmbuf, u16 rmsize);
   5.642 +;***************************************************************
   5.643 +        global  _rmcpy:near
   5.644 +        proc    _rmcpy near
   5.645 +
   5.646 +		pop	bx			;caller return address
   5.647 +                pop	ax			; rmbuf
   5.648 +		pop	cx			; rmsize
   5.649 +		push	cx
   5.650 +		push	ax
   5.651 +		push	bx
   5.652 +		push	si di es
   5.653 +		xchg	ax,si
   5.654 +		xor	di,di
   5.655 +		ifdef	NO386
   5.656 +		call	_topseg
   5.657 +		mov	es,ax
   5.658 +		else
   5.659 +		push	9000h
   5.660 +		pop	es
   5.661 +		endif
   5.662 +		cld
   5.663 +		rep
   5.664 +		  movsb
   5.665 +		extrn	_cmdline:word
   5.666 +		mov	si,[_cmdline]
   5.667 +		mov	di,8000h
   5.668 +		mov	ch,10h			; 4k
   5.669 +		rep
   5.670 +		  movsb
   5.671 +		pop	es di si
   5.672 +		ret
   5.673 +
   5.674 +        endp    _rmcpy
   5.675  
   5.676          ends    _TEXT
   5.677  
     6.1 --- a/linld/stuff/src/CRTL.H	Thu Dec 01 21:07:54 2016 +0200
     6.2 +++ b/linld/stuff/src/CRTL.H	Fri Dec 02 12:37:59 2016 +0100
     6.3 @@ -9,6 +9,14 @@
     6.4  const unsigned MIN_STACK = 0x400;
     6.5  const unsigned MAX_MALLOC = 0xF000;
     6.6  
     6.7 +const A_RDONLY    = 1;     // for fileattr()
     6.8 +const A_HIDDEN    = 2;
     6.9 +const A_SYSTEM    = 4;
    6.10 +const A_LABEL     = 8;
    6.11 +const A_DIRECTORY = 16;
    6.12 +const A_ARCHIVE   = 32;
    6.13 +
    6.14 +
    6.15  const O_RDONLY = 0;     // for open()
    6.16  const O_BINARY = 0;
    6.17  
    6.18 @@ -24,8 +32,11 @@
    6.19  extern int ximage_size, ximage_fd;
    6.20  
    6.21  void parse_cmdline();
    6.22 -extern "C" int strlen(const char* s);
    6.23 +extern "C" char* strcpy(const char* a,const char* b);
    6.24 +extern "C" char* strcat(const char* a,const char* b);
    6.25 +extern "C" char* strcatb(const char* a,const char* b);
    6.26  extern "C" int strhead(const char* a,const char* b);
    6.27 +extern "C" int fileattr(const char* name);
    6.28  extern "C" int open(const char* name, int flags);
    6.29  extern "C" int close(int fd);
    6.30  extern "C" void exit(int n);
    6.31 @@ -33,7 +44,6 @@
    6.32  extern "C" int read(int fd, void* data, int sz);
    6.33  extern "C" int write(int fd, const void* data, int sz);
    6.34  extern "C" long lseek(int fd, long sz, int dir);
    6.35 -extern "C" long rewind(int fd);
    6.36  extern "C" void* malloc(unsigned sz);
    6.37  extern "C" void puts(const char* s);
    6.38  extern "C" void putsz(const char* s);
    6.39 @@ -51,3 +61,4 @@
    6.40  extern char no_exit;
    6.41  extern "C" int die(const char* msg);
    6.42  extern "C" char* malloc_or_die(unsigned size);
    6.43 +extern "C" unsigned long* malloc_bufv_or_die(struct image_himem *m);
     7.1 --- a/linld/stuff/src/CRTLX.ASM	Thu Dec 01 21:07:54 2016 +0200
     7.2 +++ b/linld/stuff/src/CRTLX.ASM	Fri Dec 02 12:37:59 2016 +0100
     7.3 @@ -22,74 +22,31 @@
     7.4          segment _TEXT byte public use16 'CODE'
     7.5  
     7.6  ;***************************************************************
     7.7 -;char* strcpy(const char* a,const char* b);
     7.8 -;***************************************************************
     7.9 -        global  _strcpy:near
    7.10 -        proc    _strcpy near
    7.11 -
    7.12 -		mov	dl,0
    7.13 -cat:
    7.14 -		pop	cx			;caller return address
    7.15 -                pop	ax			; a
    7.16 -                pop	bx			; b
    7.17 -                push	bx
    7.18 -                push	ax
    7.19 -                push	cx
    7.20 -                push	ax si
    7.21 -                xchg	ax,si
    7.22 -		shr	dl,1
    7.23 -		jnc	@@nocat
    7.24 -@@catlp:
    7.25 -		lodsb
    7.26 -		cmp	al,0
    7.27 -                jne	@@catlp
    7.28 -		dec	si
    7.29 -@@nocat:
    7.30 -                sub	bx,si
    7.31 -@@cpylp:
    7.32 -                mov	al,[bx+si]
    7.33 -		test	dl,1
    7.34 -		jnz	@@nocpy
    7.35 -                mov	[si],al
    7.36 -                inc	si
    7.37 -		cmp	al,0
    7.38 -                jne	@@cpylp
    7.39 -                pop	si ax
    7.40 -                ret
    7.41 -@@nocpy:
    7.42 -                sub	al,[si]
    7.43 -		jnz	@@out
    7.44 -                lodsb
    7.45 -		cmp	al,0
    7.46 -                jne	@@cpylp
    7.47 -@@out:
    7.48 -		cbw
    7.49 -                pop	si dx
    7.50 -                ret
    7.51 -
    7.52 -        endp    _strcpy
    7.53 -
    7.54 -
    7.55 -;***************************************************************
    7.56 -;char* strcat(const char* a,const char* b);
    7.57 -;***************************************************************
    7.58 -        global  _strcat:near
    7.59 -        proc    _strcat near
    7.60 -
    7.61 -		mov	dl,1
    7.62 -                jmp	cat
    7.63 -
    7.64 -        endp    _strcat
    7.65 -
    7.66 -
    7.67 -;***************************************************************
    7.68  ;int strcmp(const char* a,const char* b);
    7.69  ;***************************************************************
    7.70          global  _strcmp:near
    7.71          proc    _strcmp near
    7.72  
    7.73 -		mov	dl,2
    7.74 -                jmp	cat
    7.75 +		pop	ax			;caller return address
    7.76 +                pop	cx			; a
    7.77 +                pop	bx			; b
    7.78 +                push	bx
    7.79 +                push	cx
    7.80 +                push	ax
    7.81 +                push	si
    7.82 +                mov	si,cx
    7.83 +                sub	bx,si
    7.84 +@@lp:
    7.85 +                mov	al,[bx+si]
    7.86 +                sub	al,[si]
    7.87 +		jnz	@@out
    7.88 +                lodsb
    7.89 +		cmp	al,0
    7.90 +                jne	@@lp
    7.91 +@@out:
    7.92 +		cbw
    7.93 +                pop	si
    7.94 +                ret
    7.95  
    7.96          endp    _strcmp
    7.97  
    7.98 @@ -101,31 +58,31 @@
    7.99          proc    _strstr near
   7.100  
   7.101  		pop	ax			;caller return address
   7.102 -                pop	bx			; a
   7.103 +                pop	cx			; a
   7.104                  pop	dx			; b
   7.105                  push	dx
   7.106 -                push	bx
   7.107 +                push	cx
   7.108                  push	ax
   7.109 -                push	di
   7.110 +                push	si
   7.111  @@loop:
   7.112  		xor	ax,ax
   7.113 -		cmp	[bx],al
   7.114 -		jz	@@end
   7.115 -		mov	cx,bx
   7.116 -		mov	di,dx
   7.117 -		sub	di,bx
   7.118 +		mov	si,cx
   7.119 +		cmp	[si],al			; *a
   7.120 +		jz	@@end			; return ax = NULL
   7.121 +		mov	bx,dx
   7.122 +		sub	bx,si
   7.123  @@match:
   7.124 -		mov	al,[bx+di]
   7.125 -		or	al,al
   7.126 +		or	ah,[bx+si]		; *b
   7.127  		jz	@@found
   7.128 -		inc	bx
   7.129 -		cmp	al,[bx-1]
   7.130 -		jnz	@@loop
   7.131 -		jmp	@@match
   7.132 +		lodsb
   7.133 +		sub	ah,al
   7.134 +		jz	@@match
   7.135 +		inc	cx
   7.136 +		jmp	@@loop
   7.137  @@found:
   7.138  		xchg	ax,cx
   7.139  @@end:
   7.140 -                pop	di
   7.141 +                pop	si
   7.142  		ret
   7.143  
   7.144          endp    _strstr
   7.145 @@ -370,30 +327,6 @@
   7.146  
   7.147          endp    _kver2ul
   7.148  
   7.149 -        global  N_LXURSH@:near
   7.150 -        proc    N_LXURSH@ near
   7.151 -
   7.152 -		mov	ch,0
   7.153 -@@loop:
   7.154 -		shr	dx,1
   7.155 -		rcr	ax,1
   7.156 -		loop	@@loop
   7.157 -		ret
   7.158 -
   7.159 -        endp    N_LXURSH@
   7.160 -
   7.161 -        global  N_LXLSH@:near
   7.162 -        proc    N_LXLSH@ near
   7.163 -
   7.164 -		mov	ch,0
   7.165 -@@loop:
   7.166 -		shl	ax,1
   7.167 -		rcl	dx,1
   7.168 -		loop	@@loop
   7.169 -		ret
   7.170 -
   7.171 -        endp    N_LXLSH@
   7.172 -
   7.173          ends    _TEXT
   7.174  
   7.175          end
     8.1 --- a/linld/stuff/src/CRTLX.H	Thu Dec 01 21:07:54 2016 +0200
     8.2 +++ b/linld/stuff/src/CRTLX.H	Fri Dec 02 12:37:59 2016 +0100
     8.3 @@ -1,10 +1,9 @@
     8.4  // This file is distributed under GPL
     8.5  //
     8.6  #define NULL 0
     8.7 +extern "C" int strcmp(const char* a,const char* b);
     8.8 +extern "C" int strlen(const char* s);
     8.9  extern "C" char* strstr(const char* a,const char* b);
    8.10 -extern "C" char* strcat(const char* a,const char* b);
    8.11 -extern "C" char* strcpy(const char* a,const char* b);
    8.12 -extern "C" int strcmp(const char* a,const char* b);
    8.13  extern "C" int cpuhaslm();
    8.14  extern "C" char *progname(void);
    8.15  extern "C" int chdir(char *path);
     9.1 --- a/linld/stuff/src/HIMEM.CPP	Thu Dec 01 21:07:54 2016 +0200
     9.2 +++ b/linld/stuff/src/HIMEM.CPP	Fri Dec 02 12:37:59 2016 +0100
     9.3 @@ -6,91 +6,29 @@
     9.4  #include "crtl.h"
     9.5  #include "common.h"
     9.6  
     9.7 -// Returns physical addr of allocated himem chunk
     9.8 -// Never fails (will use fallback if not enough mem/no xmm)
     9.9 -// TODO: with proper cleanup it is possible to exit to DOS
    9.10 -// even after XMM alloc - do dealloc, then exit...
    9.11 -// don't forget to clean up the mess then, especially
    9.12 -// XMM handle which is lost inside xmm_alloc()...
    9.13 -// (don't drop fallback: use it if no XMM driver detected)
    9.14 -static void read2mem(struct image_himem *m) {
    9.15 -    u32 buf=m->buf;
    9.16 -    while(1) {
    9.17 -	u8 xfer_buf[PAGE_SIZE];
    9.18 -        u16 size = read_image(m, xfer_buf, sizeof(xfer_buf));
    9.19 -        if(s16(size) <= 0) break;
    9.20 -        memcpy32(0, buf, seg(xfer_buf), ofs(xfer_buf), size);
    9.21 -        buf += size;
    9.22 -        m->remaining -= size;
    9.23 -    }
    9.24 -}
    9.25 -
    9.26 -extern "C" void sort(u32* v, int size);
    9.27 -
    9.28 -// Returns ptr to mallocated zero-terminated list of physical page addrs
    9.29 -// Never fails (will die if not enough mem)
    9.30 -// Addresses are sorted in ascending order
    9.31 -// static void malloc_vcpi(struct image_himem *m) {
    9.32 -static void read2vcpi(struct image_himem *m) {
    9.33 -    u16 cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
    9.34 -    u32* bufv = (u32*)malloc_or_die((cnt+1)*sizeof(u32));
    9.35 -    // our malloc zeroes allocated mem: buf[cnt]=0;
    9.36 -    // Allocate pages, storing addrs in addrbuf
    9.37 -    {for(int i=0;i<cnt;i++) {
    9.38 -        u32 v;
    9.39 -        asm {
    9.40 -                db      66h
    9.41 -                xor     dx,dx
    9.42 -                mov     ax,0DE04h
    9.43 -                int     67h
    9.44 -                db      66h
    9.45 -                mov     [word ptr v],dx
    9.46 -        }
    9.47 -        extern const char vcpi_alloc_err[];
    9.48 -        if(!v) die(vcpi_alloc_err);
    9.49 -        bufv[i] = v;
    9.50 -    }}
    9.51 -    // Sanitize addresses: ascending sort
    9.52 -    sort(bufv,cnt);
    9.53 -    m->bufv = bufv;
    9.54 -//}
    9.55 -
    9.56 -// Reads opened fd data into malloc_vcpi'ed memory
    9.57 -// Dies if file isn't exactly 'size' bytes long
    9.58 -// Needs intermediate buffer of exactly Nx4k bytes
    9.59 -// static void read2vcpi(struct image_himem *m) {
    9.60 -    while(1) {
    9.61 -	u8 xfer_buf[PAGE_SIZE];
    9.62 -        u16 size = read_image(m, xfer_buf, PAGE_SIZE);
    9.63 -        if(s16(size) <= 0 || !*bufv) break;
    9.64 -        m->remaining -= size;
    9.65 -        memcpy_vcpi(*bufv++, seg(xfer_buf), ofs(xfer_buf));
    9.66 -    }
    9.67 -}
    9.68 -
    9.69 -void init_vcpi() {
    9.70 -    heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
    9.71 -    get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
    9.72 -}
    9.73 -
    9.74  int skip_xmmalloc;
    9.75  void load_image(struct image_himem *m) {
    9.76      no_exit++;       // die() won't return to DOS
    9.77      m->remaining = m->size;
    9.78 -    m->buf = m->fallback;
    9.79 -    if(m->fallback < _1m) {
    9.80 -        read2mem(m);
    9.81 -    } else if(vcpi==0) {
    9.82 -	if (!skip_xmmalloc) {
    9.83 -        	u32 v = xmm_alloc(m->size);
    9.84 -        	if(v) m->buf = v;
    9.85 +    u32 buf= m->buf = m->fallback;
    9.86 +    u32* bufv= &buf;
    9.87 +    if(m->fallback >= _1m) {
    9.88 +	if(vcpi) {
    9.89 +	    bufv = malloc_bufv_or_die(m);
    9.90  	}
    9.91 -        read2mem(m);
    9.92 -    } else {
    9.93 -        //malloc_vcpi(m);
    9.94 -        read2vcpi(m);
    9.95 +	else if (!skip_xmmalloc) {
    9.96 +            xmm_alloc(m);
    9.97 +	}
    9.98      }
    9.99 +    do {
   9.100 +	u8 xfer_buf[PAGE_SIZE];
   9.101 +        u16 size = read_image(m, xfer_buf, PAGE_SIZE);
   9.102 +        if(s16(size) <= 0) break;
   9.103 +        memcpy32(*bufv, seg(xfer_buf), ofs(xfer_buf), size);
   9.104 +	if (bufv != &buf) bufv++;
   9.105 +        buf += size;
   9.106 +    } while (*bufv);
   9.107      if(m->remaining) die("Read error");
   9.108 -//break iso case    close(m->fd);
   9.109 +    close(m->fd2close);
   9.110  }
   9.111  
    10.1 --- a/linld/stuff/src/JUMP.ASM	Thu Dec 01 21:07:54 2016 +0200
    10.2 +++ b/linld/stuff/src/JUMP.ASM	Fri Dec 02 12:37:59 2016 +0100
    10.3 @@ -39,14 +39,14 @@
    10.4  		mov	bx,[word _pm+2+2]	; get pm->fallback high word
    10.5  		; self move
    10.6  		cld
    10.7 -	;	push	9940h			; 5120 bytes for cmdline
    10.8 -	push	9820h			; 512 bytes for cmdline
    10.9 -		pop	es			; min 1024 bytes for stack
   10.10 -		xor	si,si			;  A000 -9400 -0800(>movedend)
   10.11 +		push	9900h			; 4096 bytes for cmdline
   10.12 +	;push	9820h			; 512 bytes for cmdline
   10.13 +		pop	es			; min 2048 bytes for stack
   10.14 +		xor	si,si			;  A000 -9000 -0800(>movedend)
   10.15  		xor	di,di			; set ZF
   10.16 -	;	mov	cx,offset movedend
   10.17 +		mov	cx,offset movedend
   10.18          global  _bss_end:byte
   10.19 -	mov	cx,offset _bss_end
   10.20 +	;mov	cx,offset _bss_end
   10.21  		rep
   10.22  		  movsb
   10.23  		push	es
   10.24 @@ -62,12 +62,17 @@
   10.25  		jnc	nomove
   10.26  		push	cs
   10.27  		pop	ds
   10.28 +		push	bx
   10.29  		call	near dos_shutdown
   10.30 +		;in	al,70h
   10.31 +		;or	al,80h			; disable NMI
   10.32 +		;out	70h,al
   10.33 +		pop	bx
   10.34  		; move zImage pm
   10.35  		mov	ax,8
   10.36  		cwd
   10.37  		cmp	bx,ax
   10.38 -		jnb	bufhigh
   10.39 +		ja	bufhigh
   10.40  		sub	ax,bx
   10.41  		inc	ax
   10.42  bufhigh:
   10.43 @@ -78,10 +83,9 @@
   10.44  		push	dx			; srcseg=0
   10.45  		push	1			; dst
   10.46  		push	dx			;    ofs=64k
   10.47 -		push	dx			; dstseg=0
   10.48  		extrn   _memcpy32:near
   10.49  		call	_memcpy32
   10.50 -		add	sp,16
   10.51 +		add	sp,14
   10.52  
   10.53  		ifndef  noelks
   10.54  		push	ss
    11.1 --- a/linld/stuff/src/LINLD.CPP	Thu Dec 01 21:07:54 2016 +0200
    11.2 +++ b/linld/stuff/src/LINLD.CPP	Fri Dec 02 12:37:59 2016 +0100
    11.3 @@ -5,28 +5,6 @@
    11.4  #include "crtl.h"
    11.5  #include "common.h"
    11.6  
    11.7 -static struct image_himem image;
    11.8 -static const char msg_cmdline[] = "Error reading cl=@file";
    11.9 -static char* read_cmdline_or_die(const char* fn) {
   11.10 -    image.errmsg = msg_cmdline;
   11.11 -    open_image(fn, &image);
   11.12 -    u16 size=image.size;
   11.13 -    char *cmdline_buf;
   11.14 -    if(size>=PAGE_SIZE ||
   11.15 -       !(cmdline_buf=(char *)malloc(size)) ||
   11.16 -       read(image.fd, cmdline_buf, size) != size)
   11.17 -        die(msg_cmdline);
   11.18 -    // Strip any trailing cr/lf
   11.19 -    char *p=cmdline_buf+size;
   11.20 -    char c='\0';
   11.21 -    do {
   11.22 -        // Replace all other cr/lfs with spaces
   11.23 -        if(*--p>=' ') c=' ';
   11.24 -	else *p = c;
   11.25 -    } while (p>cmdline_buf);
   11.26 -    return cmdline_buf;
   11.27 -}
   11.28 -
   11.29  const char* kernel_name = "bzImage";
   11.30  const char* initrd_name;
   11.31  const char* cmdline = "auto";
   11.32 @@ -40,13 +18,14 @@
   11.33      die("Syntax:" NL
   11.34          "LINLD [image=file] [initrd=files] [vga=mode] [root=num] [mem=max] [cl=cmdline]" NL
   11.35          "vga mode: ask,extended,normal or dec/oct/hex number" NL
   11.36 +        "-f force" NL
   11.37          "Defaults:" NL
   11.38          "\timage=bzImage" NL
   11.39          "\tinitrd,vga,root=(void)" NL
   11.40          "\tmem=256m" NL
   11.41          "\tcl=auto" NL
   11.42          "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
   11.43 -        "Use cl=@filename to take cmdline from file"
   11.44 +        "Use cl=@filename to get it from a file"
   11.45  #if 1
   11.46          NL NL "Examples:" NL
   11.47          "\tlinld initrd=rootfs4.gz,rootfs3.gz,rootfs2.gz,rootfs1.gz \"cl=rw root=/dev/null video=-32\""
   11.48 @@ -55,59 +34,88 @@
   11.49      );
   11.50  }
   11.51  
   11.52 +static char _cmdline[256];
   11.53  int main(int argc, char *argv[]) {
   11.54      // Believe it or not - this enables A20
   11.55      // on my box! Must be DOS in HMA...   -vda
   11.56      puts("LINLD v" VERSION_STR "+");
   11.57  
   11.58 -    // Parse command line
   11.59 -
   11.60      if(argc<2) {
   11.61  dosyntax:
   11.62          syntax();
   11.63      }
   11.64 -    {for(int i=1;i<argc;i++) {
   11.65 -	char *s=argv[i];
   11.66 +
   11.67 +    // Parse command line
   11.68 +    {for (char i=0;;) {
   11.69 +	char *s=*++argv;
   11.70 +	i++;
   11.71 +	if (!s) {
   11.72 +	    puts(load_kernel());
   11.73 +	    load_initrd();
   11.74 +	    boot_kernel();
   11.75 +	}
   11.76          if(strhead(s,"image=") == 0) {
   11.77 -            kernel_name=s+6;
   11.78 +	    s+=6;
   11.79 +            kernel_name=s;
   11.80          }
   11.81          else if(strhead(s,"initrd=") == 0) {
   11.82 -            initrd_name = s+7;
   11.83 +	    s+=7;
   11.84 +            initrd_name=s;
   11.85 +        }
   11.86 +        else if((*(u16 *)s|0x2002) == 0x662F) { // -F /f
   11.87 +            extern int skip_xmmalloc;
   11.88 +            skip_xmmalloc++;
   11.89 +        }
   11.90 +        else if(strhead(s,"vga=") == 0) {
   11.91 +	    s+=4;
   11.92 +            vid_mode = strtol(s);	// support normal, extended & ask
   11.93          }
   11.94          else if(strhead(s,"cl=") == 0) {
   11.95 -            cmdline=s+3;
   11.96 -            if (cmdline[0] == '@') {
   11.97 -                cmdline=read_cmdline_or_die(cmdline+1);
   11.98 +            cmdline=s+=3;
   11.99 +            if (*s == '@') {
  11.100 +		static struct image_himem image;
  11.101 +		char c;
  11.102 +
  11.103 +		s++;
  11.104 +		image.errmsg = "Error in cl=@file";
  11.105 +		open_image(s, &image);
  11.106 +		cmdline=s=(char *)malloc_or_die(image.size);
  11.107 +		s+=image.size;
  11.108 +		read(image.fd, (void *)cmdline, image.size);
  11.109 +		// Strip any trailing cr/lf
  11.110 +		c='\0';
  11.111 +		do {
  11.112 +			// Replace all other cr/lfs with spaces
  11.113 +			s--;
  11.114 +			if(*s>=' ') c=' ';
  11.115 +			else *s = c;
  11.116 +		} while (s>cmdline);
  11.117                  puts("Kernel command line:");
  11.118                  puts(cmdline);
  11.119              }
  11.120          }
  11.121 -        else if(strhead(s,"vga=") == 0) {
  11.122 -	    s+=4;
  11.123 -	    const char c = *s|0x20;
  11.124 -            if (c == 'a') vid_mode = -3;
  11.125 -            else if (c == 'e') vid_mode = -2;
  11.126 -            else if (c == 'n') vid_mode = -1;
  11.127 -            else vid_mode = strtol(s);
  11.128 -        }
  11.129          else if(strhead(s,"root=") == 0) {
  11.130 -            root_dev = strtol(s+5);
  11.131 +	    s+=5;
  11.132 +            root_dev = strtol(s);
  11.133 +	    goto addincmdline;
  11.134          }
  11.135          else if(strhead(s,"mem=") == 0) {
  11.136 -            topmem = strtol(s+4);
  11.137 +	    s+=4;
  11.138 +            topmem = strtol(s);
  11.139 +	    goto addincmdline;
  11.140          }
  11.141 -        else if(strhead(s,"-f") == 0) {
  11.142 -            extern int skip_xmmalloc;
  11.143 -            skip_xmmalloc++;
  11.144 +        else if(cmdline == (const char *) _cmdline) {
  11.145 +addincmdline:
  11.146 +	    strcatb(_cmdline,*argv);
  11.147          }
  11.148 -        else
  11.149 -            goto dosyntax;
  11.150 +	else if(i == 1 && fileattr(s) != -1) {
  11.151 +            kernel_name = s;
  11.152 +	    cmdline = (const char *) _cmdline;
  11.153 +        }
  11.154 +	else
  11.155 +	    goto dosyntax;
  11.156      }}
  11.157  
  11.158 -    puts(load_kernel());
  11.159 -    load_initrd();
  11.160 -    boot_kernel();
  11.161 -
  11.162      // Let compiler be happy
  11.163 -    return _AX;
  11.164 +    // return _AX;
  11.165  }
    12.1 --- a/linld/stuff/src/LOAD.CPP	Thu Dec 01 21:07:54 2016 +0200
    12.2 +++ b/linld/stuff/src/LOAD.CPP	Fri Dec 02 12:37:59 2016 +0100
    12.3 @@ -43,23 +43,8 @@
    12.4  00000000+------------------------+
    12.5  */
    12.6  
    12.7 -struct first1k_t {
    12.8 -                            // these two set by rm setup:
    12.9 -    u16     curr_curs;      // 0000 saved cursor position
   12.10 -    u16     ext_mem_size;   // 0002 extended memory size in Kb (from int 0x15 fn 0x88)
   12.11 -    u8      pad00[0x20-4];
   12.12 -                            // old-style cmdline (not used in LINLD (yet?))
   12.13 -    u16     cl_magic;       // 0020 commandline magic number (=0xA33F)
   12.14 -    u16     cl_ofs;         // 0022 commandline offset
   12.15 -    u8      pad10[0x80-0x24];
   12.16 -                            // these two set by rm setup:
   12.17 -    u8      hd0_disk_par[16]; // 0080 hd0-disk-parameter from intvector 0x41
   12.18 -    u8      hd1_disk_par[16]; // 0090 hd1-disk-parameter from intvector 0x46
   12.19 -    u8      pad20[0x01e0-0xa0];
   12.20 -                            // this is set by rm setup:
   12.21 -    u32     alt_mem_size;   // 01E0 extended memory size in Kb (from int 0x15 fn 0xe801)
   12.22 -    u8      pad28[0x01f1-0x1e4];
   12.23 -
   12.24 +struct kernelparams_t {
   12.25 +    u8      pad0;
   12.26      u8      setup_sects;    // 01F1 The size of the setup in sectors
   12.27                              //      boot sector is NOT included here
   12.28      u16     ro_flag;        // 01F2 If set, the root is mounted readonly
   12.29 @@ -101,6 +86,25 @@
   12.30                              // int 0x15 fn 0xe820
   12.31  }; //__attribute((packed));
   12.32  
   12.33 +struct first1k_t {
   12.34 +                            // these two set by rm setup:
   12.35 +    u16     curr_curs;      // 0000 saved cursor position
   12.36 +    u16     ext_mem_size;   // 0002 extended memory size in Kb (from int 0x15 fn 0x88)
   12.37 +    u8      pad00[0x20-4];
   12.38 +                            // old-style cmdline (not used in LINLD (yet?))
   12.39 +    u16     cl_magic;       // 0020 commandline magic number (=0xA33F)
   12.40 +    u16     cl_ofs;         // 0022 commandline offset
   12.41 +    u8      pad10[0x80-0x24];
   12.42 +                            // these two set by rm setup:
   12.43 +    u8      hd0_disk_par[16]; // 0080 hd0-disk-parameter from intvector 0x41
   12.44 +    u8      hd1_disk_par[16]; // 0090 hd1-disk-parameter from intvector 0x46
   12.45 +    u8      pad20[0x01e0-0xa0];
   12.46 +                            // this is set by rm setup:
   12.47 +    u32     alt_mem_size;   // 01E0 extended memory size in Kb (from int 0x15 fn 0xe801)
   12.48 +    u8      pad28[0x01f0-0x1e4];
   12.49 +    struct kernelparams_t params;
   12.50 +}; //__attribute((packed));
   12.51 +
   12.52  #if sizeof(first1k_t)!=0x400
   12.53  #error BUG: Bad first1k
   12.54  #endif
   12.55 @@ -116,7 +120,7 @@
   12.56  static void memcpy_image(struct image_himem *m) {
   12.57      if (m->fallback != m->buf)
   12.58          memcpy32(
   12.59 -            0, m->fallback, // dst seg,ofs
   12.60 +            m->fallback,    // dst seg,ofs
   12.61              0, m->buf,      // src seg,ofs
   12.62              m->size         // size
   12.63          );
   12.64 @@ -152,7 +156,7 @@
   12.65          // Move kernel
   12.66          // 'Gathering' copy in chunks of PAGE_SIZE
   12.67          // No risk of overlapping: kernel is copied from above to 1m mark
   12.68 -        pm.size = PAGE_SIZE;
   12.69 +        pm.size = initrd.size = PAGE_SIZE;
   12.70          u32 *p = pm.bufv;
   12.71          if (p) while(*p) {
   12.72              pm.buf = *p;
   12.73 @@ -167,7 +171,6 @@
   12.74              // (overlapping still can happen with more than 256mb ram)
   12.75              // (generic solution for this overwrite problem, anyone?)
   12.76              p=initrd.bufv;
   12.77 -            initrd.size = PAGE_SIZE;
   12.78              do {
   12.79                  p++; initrd.fallback+=PAGE_SIZE;
   12.80              } while(*p);
   12.81 @@ -216,7 +219,9 @@
   12.82      char *version_string;
   12.83    {
   12.84      struct first1k_t *first1k;
   12.85 +    struct kernelparams_t *kernelparams;
   12.86      first1k = (first1k_t*) (rm_buf = malloc_or_die(_32k));
   12.87 +    kernelparams = &first1k->params;
   12.88     {
   12.89      u16 rm_seek;
   12.90  
   12.91 @@ -226,7 +231,7 @@
   12.92          die(kernel_file_error);
   12.93      }
   12.94  
   12.95 -    if(!first1k->setup_sects) {
   12.96 +    if(!kernelparams->setup_sects) {
   12.97  #if 1
   12.98          if(* (int *) &first1k->pad10[0x3F-0x24] == 0x3AE8) {
   12.99              lseek(pm.fd,rm_seek=0x200,SEEK_SET);
  12.100 @@ -234,10 +239,10 @@
  12.101          }
  12.102          else
  12.103  #endif
  12.104 -        first1k->setup_sects=4;
  12.105 +        kernelparams->setup_sects=4;
  12.106      }
  12.107 -    rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
  12.108 -    if(rm_size>_32k || first1k->boot_flag != 0xAA55)
  12.109 +    rm_size = 0x200*(kernelparams->setup_sects+1); // 0th sector is not counted there
  12.110 +    if(rm_size>_32k || kernelparams->boot_flag != 0xAA55)
  12.111          die("It's not a kernel");
  12.112      heap_top = rm_buf+rm_size;  // <*>
  12.113  
  12.114 @@ -251,15 +256,15 @@
  12.115  
  12.116      // Tell rm loader some info
  12.117  
  12.118 -    if(vid_mode) first1k->vid_mode = vid_mode;
  12.119 -    if(root_dev) first1k->root_dev = root_dev;
  12.120 +    if(vid_mode) kernelparams->vid_mode = vid_mode;
  12.121 +    if(root_dev) kernelparams->root_dev = root_dev;
  12.122      version_string = 0;
  12.123  
  12.124  #if 1
  12.125 -    if(first1k->header == HdrS) { // starting linux 1.3.73
  12.126 -	if(first1k->loadflags & 1) {
  12.127 +    if(kernelparams->header == HdrS) { // starting linux 1.3.73
  12.128 +	if(kernelparams->loadflags & 1) {
  12.129  #else
  12.130 -    if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
  12.131 +    if((kernelparams->header != HdrS) || (kernelparams->loadflags & 1) == 0)
  12.132          die("I can't load bzImage low");
  12.133      {
  12.134          {
  12.135 @@ -270,23 +275,23 @@
  12.136              hook_int15_88();
  12.137  
  12.138              // * will be called just before rm -> pm
  12.139 -            first1k->realmode_switch_ofs = ofs(last_ditch);
  12.140 -            first1k->realmode_switch_seg = seg(last_ditch);
  12.141 +            kernelparams->realmode_switch_ofs = ofs(last_ditch);
  12.142 +            kernelparams->realmode_switch_seg = seg(last_ditch);
  12.143          }
  12.144 -        if(first1k->kernel_version)
  12.145 -            version_string = (char *) first1k+first1k->kernel_version+0x200;
  12.146 -        first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
  12.147 -        if(first1k->version >= 0x201) {
  12.148 +        if(kernelparams->kernel_version)
  12.149 +            version_string = (char *) first1k+kernelparams->kernel_version+0x200;
  12.150 +        kernelparams->type_of_loader = 0xff; // kernel do not know us (yet :-)
  12.151 +        if(kernelparams->version >= 0x201) {
  12.152              // * offset limit of the setup heap
  12.153              //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
  12.154 -            first1k->heap_end_ptr = _32k-0x0200;
  12.155 -            first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
  12.156 +            kernelparams->heap_end_ptr = _32k-0x0200;
  12.157 +            kernelparams->loadflags |= 0x80; // says to rm loader it's ok to use heap
  12.158          }
  12.159          // * if we will ever stop moving ourself to 0x90000
  12.160          //   we must say setup.S how much to move
  12.161 -        //first1k->setup_move_size = _32k;
  12.162 -        if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
  12.163 -            first1k->cmd_line_ptr = (((u32)(topseg()+0x0800))<<4);
  12.164 +        //kernelparams->setup_move_size = _32k;
  12.165 +        if(kernelparams->version >= 0x202) { // starting linux 2.4.0-test3-pre3
  12.166 +            kernelparams->cmd_line_ptr = (((u32)(topseg()+0x0800))<<4);
  12.167              goto cmd_line_ok;
  12.168          }
  12.169      }
  12.170 @@ -304,6 +309,7 @@
  12.171  
  12.172      pm.fallback = (u32((u16(_CS)+0x1FFF)&0xF000)<<4);
  12.173      pm.size -= rm_size;
  12.174 +    pm.chunk_size -= rm_size;
  12.175      if(pm.fallback+pm.size > (((u32)topseg())<<4) || pm_high) {
  12.176          pm.fallback = _1m+_64k;
  12.177      }
  12.178 @@ -314,16 +320,15 @@
  12.179  
  12.180  // Read initrd if needed
  12.181  
  12.182 -static const char msg_initrd[] = "Can't use initrd file";
  12.183  void load_initrd() {
  12.184      struct image_himem *m = &initrd;
  12.185      if (!initrd_name && !initrd.fd) return;
  12.186 -    if (!pm.fd) {
  12.187 +    m->errmsg = "Can't use initrd file";
  12.188 +    if (!pm.errmsg) {
  12.189  noinitrd:
  12.190 -        puts(msg_initrd);
  12.191 +        puts(m->errmsg);
  12.192          return;
  12.193      }
  12.194 -    m->errmsg = msg_initrd;
  12.195      open_image(initrd_name, m);
  12.196  
  12.197      m->fallback = (memtop()-m->size) & (~PAGE_MASK);
  12.198 @@ -333,10 +338,10 @@
  12.199      }
  12.200  
  12.201      load_image(m);
  12.202 -    struct first1k_t *first1k = (first1k_t*)rm_buf;
  12.203 -    if(first1k->header == HdrS) {
  12.204 -        first1k->initrd_buf  = m->fallback;
  12.205 -        first1k->initrd_size = m->size;
  12.206 +    struct kernelparams_t *kernelparams = (kernelparams_t *)(rm_buf+0x1F0);
  12.207 +    if(kernelparams->header == HdrS) {
  12.208 +        kernelparams->initrd_buf  = m->fallback;
  12.209 +        kernelparams->initrd_size = m->size;
  12.210      }
  12.211  }
  12.212  
  12.213 @@ -355,29 +360,8 @@
  12.214      cli(); // we start doing destructive things to DOS
  12.215  
  12.216      // Move rm loader & commandline to 0x90000
  12.217 -    if(vcpi==0) {
  12.218 -        memcpy32(
  12.219 -            topseg(),0,
  12.220 -            seg(rm_buf),ofs(rm_buf),
  12.221 -            rm_size //_32k
  12.222 -        );
  12.223 -        memcpy32(
  12.224 -            topseg()+0x0800,0,
  12.225 -            seg(cmdline),ofs(cmdline),
  12.226 -            PAGE_SIZE
  12.227 -        );
  12.228 -    } else { //vcpi
  12.229 -        u32 dst=((u32)topseg()<<4);
  12.230 -        u16 pos=ofs(rm_buf);
  12.231 -        do {
  12.232 -            memcpy_vcpi(dst,seg(rm_buf),pos);
  12.233 -            dst+=PAGE_SIZE;
  12.234 -            pos+=PAGE_SIZE;
  12.235 -            rm_size-=PAGE_SIZE;
  12.236 -          } while(s16(rm_size) > 0);
  12.237 -        // overkill: copy PAGE_SIZE bytes
  12.238 -        memcpy_vcpi(((u32)(topseg()+0x0800)<<4),seg(cmdline),ofs(cmdline));
  12.239 -    }
  12.240 +    // overkill: copy PAGE_SIZE bytes
  12.241 +    rmcpy(rm_buf, rm_size);
  12.242  
  12.243      // Jump to kernel rm code
  12.244      set_sregs_jump_seg_ofs(csip, sssp);
    13.1 --- a/linld/stuff/src/MEMCPY32.ASM	Thu Dec 01 21:07:54 2016 +0200
    13.2 +++ b/linld/stuff/src/MEMCPY32.ASM	Fri Dec 02 12:37:59 2016 +0100
    13.3 @@ -12,6 +12,7 @@
    13.4  
    13.5          segment _DATA byte public use16 'DATA'
    13.6  msg_badcpu      db      "I need 386+ CPU in real mode or under VCPI manager",0
    13.7 +msg_badmapping  db      "VCPI: low 640k: need 1:1 mapping",0
    13.8          ends    _DATA
    13.9  
   13.10          segment _TEXT byte public use16 'CODE'
   13.11 @@ -27,7 +28,7 @@
   13.12          proc    _is_vm86 near
   13.13  
   13.14  ; Check for oldies
   13.15 -		mov	ax, 0F000h
   13.16 +		mov	ah, 0F0h
   13.17  		pushf
   13.18  		push	ax		; < 286 : flags[12..15] are forced 1
   13.19  		popf			; = 286 : flags[12..15] are forced 0
   13.20 @@ -64,14 +65,14 @@
   13.21                  mov     ds,[word 67h*4+2]
   13.22                  cmp     [dword 10+4],'0XXX'
   13.23                  jne     @@skip
   13.24 -                mov     eax,[dword 10]
   13.25 -                cmp     eax,'XMME'
   13.26 -                je      @@skip
   13.27 -        ; this also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
   13.28 -                cmp     eax,'QMME'
   13.29 +                mov     eax,'XMME'
   13.30 +                xor     eax,[dword 10]
   13.31 +        ; QMME also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
   13.32 +                shl     eax,8
   13.33  @@skip:
   13.34                  pop     ds
   13.35                  jne     @@no_vcpi
   13.36 +
   13.37  ; Check emm manager status and version
   13.38                  mov     ah,40h          ; get status
   13.39                  int     67h
   13.40 @@ -101,11 +102,18 @@
   13.41  @@no_vcpi:
   13.42  		mov	bx,offset msg_badcpu
   13.43                  extrn   die:near
   13.44 +godie:
   13.45  		jmp	near die
   13.46  @@386vcpi:
   13.47  		mov	[_vcpi],al
   13.48 -                extrn	@init_vcpi$qv:near
   13.49 -                jmp	near @init_vcpi$qv
   13.50 +                extrn   prepare_vcpi:near
   13.51 +		call	prepare_vcpi
   13.52 +;    get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
   13.53 +                ;extrn   _get_vcpi_interface:near
   13.54 +		;call	_get_vcpi_interface
   13.55 +		mov	bx,offset msg_badmapping
   13.56 +		jz	godie
   13.57 +		ret
   13.58  
   13.59          endp    _is_vm86
   13.60  
   13.61 @@ -116,16 +124,26 @@
   13.62          global  dos_shutdown:near
   13.63          proc    dos_shutdown near
   13.64  
   13.65 -;TODO NO386
   13.66  dos_shutdown:
   13.67 -		pusha
   13.68 +		ifndef	NO386
   13.69 +		;pusha
   13.70 +		else
   13.71 +		;push	bp si di
   13.72 +		endif
   13.73  		xor	bx,bx
   13.74  		mov	ds,bx
   13.75 +		ifndef	NO386
   13.76  		push	[dword bx+4]		; save step
   13.77  		mov	ax,sp
   13.78  		push	ss
   13.79  		push	ax
   13.80  		pop	[dword cs:sssp]
   13.81 +		else
   13.82 +		push	[word bx+6]	
   13.83 +		push	[word bx+4]		; save step
   13.84 +		mov	[word cs:sssp],sp
   13.85 +		mov	[word cs:sssp+2],ss
   13.86 +		endif
   13.87  		;cmp	[byte bx+7],0F0h
   13.88  		;jnc	notdos
   13.89  		mov	[word bx+4],offset step19
   13.90 @@ -150,11 +168,24 @@
   13.91  		pop	bx
   13.92  		jne	doiret
   13.93  notdos:
   13.94 +		ifndef	NO386
   13.95  		lss	sp,[dword cs:sssp]
   13.96 +		else
   13.97 +		lds	bx,[dword cs:sssp]
   13.98 +		push	ds
   13.99 +		pop	ss
  13.100 +		mov	sp,bx
  13.101 +		endif
  13.102  		xor	bx,bx
  13.103  		mov	ds,bx
  13.104 +		ifndef	NO386
  13.105  		pop	[dword bx+4]		; restore step
  13.106 -		popa
  13.107 +		;popa
  13.108 +		else
  13.109 +		pop	[word bx+4]		; restore step
  13.110 +		pop	[word bx+6]
  13.111 +		;pop	di si bp
  13.112 +		endif
  13.113  		push	cs
  13.114  		pop	ds
  13.115  		ret
  13.116 @@ -163,22 +194,20 @@
  13.117  
  13.118  
  13.119  ;***************************************************************
  13.120 -;void memcpy32(u16 dstseg,u32 dstofs,u16 srcseg,u32 srcofs,u32 size);
  13.121 +;void memcpy32(u32 dstofs,u16 srcseg,u32 srcofs,u32 size);
  13.122  ;***************************************************************
  13.123  ;****** Uses:   Flags
  13.124  ;***************************************************************
  13.125          global  _memcpy32:near
  13.126          proc    _memcpy32 near
  13.127  
  13.128 -;TODO NO386
  13.129  ; rm32,imm16 helper
  13.130  macro   addzx_e rm,i
  13.131          db      66h
  13.132          add     rm,i
  13.133          dw      0
  13.134  endm
  13.135 -                arg     dstseg  :word,  \
  13.136 -                        dstofs  :dword, \
  13.137 +                arg     dstofs  :dword, \
  13.138                          srcseg  :word,  \
  13.139                          srcofs  :dword, \
  13.140                          sz      :dword  = PARAM_SIZE
  13.141 @@ -187,97 +216,114 @@
  13.142                          oldGDTR :pword  = TEMP_SIZE
  13.143  
  13.144  ;****** Init ***************************************************
  13.145 -                enter   TEMP_SIZE,0
  13.146 +		push	bp
  13.147 +		mov	bp,sp
  13.148 +		sub	sp,TEMP_SIZE
  13.149                  pushf
  13.150 -                push    es ds esi edi
  13.151 +		cld
  13.152 +                push    ds es
  13.153 +
  13.154 +			ifndef	NO386
  13.155 +
  13.156 +                pushad
  13.157                  movzx   esi,[srcseg]
  13.158                  shl     esi,4
  13.159 -                add     esi,[srcofs]
  13.160 -                movzx   edi,[dstseg]
  13.161 -                shl     edi,4
  13.162 -                add     edi,[dstofs]
  13.163 +                add     [srcofs],esi
  13.164 +                mov     esi,[srcofs]
  13.165 +                mov     edi,[dstofs]
  13.166 +
  13.167  	ifndef	pm_only
  13.168 -		mov	eax,00100000h
  13.169 -		cmp	esi,eax
  13.170 -                jnb     pmcopy
  13.171 -		cmp	edi,eax
  13.172 -                jnb     pmcopy
  13.173 +		mov	eax,esi
  13.174 +		or	eax,edi
  13.175 +		shr	eax,20			; >1mb ?
  13.176 +                jnz     pmcopy
  13.177  		mov	eax,esi
  13.178  		shr	eax,4
  13.179 -		mov	ds,ax
  13.180  		mov	edx,edi
  13.181  		shr	edx,4
  13.182  @@movlp:
  13.183  		mov	ds,ax
  13.184  		mov	es,dx
  13.185 -		and	si,0Fh
  13.186 -		and	di,0Fh
  13.187 -		mov	cx,08h
  13.188 -		cld
  13.189 -            rep movsw
  13.190  		inc	ax
  13.191  		inc	dx
  13.192 -                sub     [sz],10h
  13.193 +		xor	ecx,ecx
  13.194 +		mov	cl,0Fh
  13.195 +		and	si,cx
  13.196 +		and	di,cx
  13.197 +		inc	cx
  13.198 +                sub     [sz],ecx
  13.199 +            rep movsb
  13.200                  ja	@@movlp
  13.201  		jmp	done
  13.202  	endif
  13.203  pmcopy:
  13.204 +			else
  13.205 +
  13.206 +		push	si
  13.207 +		xor	bx,bx
  13.208 +		xor	dx,dx
  13.209 +		xor	si,si
  13.210 +		mov	ax,[bp+si+8]		; srcseg
  13.211 +		call	near N_LXLSH@4
  13.212 +		add	[bp+si+10],ax		; srcofs lo
  13.213 +		adc	[bp+si+10+2],dx		; srcofs hi
  13.214 +@@2flat:
  13.215 +		mov	ax,[bp+si+10]		; srcofs, dstofs lo
  13.216 +		mov	dx,[bp+si+10+2]		; srcofs, dstofs hi
  13.217 +		call	near N_LXURSH@4
  13.218 +		or	bx,dx			; >=1mb flag
  13.219 +		push	ax			; srcseg, dstseg
  13.220 +		xor	si,-6
  13.221 +		jnz	@@2flat
  13.222 +		pop	dx			; dstseg
  13.223 +		pop	ax			; srcseg
  13.224 +		or	bx,bx			; <1mb ?
  13.225 +                jnz     pmcopy
  13.226 +		push	di
  13.227 +@@movlp:
  13.228 +		mov	ds,ax
  13.229 +		mov	es,dx
  13.230 +		inc	ax
  13.231 +		inc	dx
  13.232 +		mov	cl,0Fh
  13.233 +		mov	si,cx
  13.234 +		mov	di,cx
  13.235 +		and	si,[word srcofs]
  13.236 +		and	di,[word dstofs]
  13.237 +		inc	cx
  13.238 +                sub     [word sz],cx
  13.239 +            rep movsb
  13.240 +		jae	@@movlp
  13.241 +		dec	[word sz+2]
  13.242 +                jns	@@movlp			; mov 1-16 more bytes...
  13.243 +		pop	di si
  13.244 +		jmp	done16
  13.245 +pmcopy:
  13.246 +		pop	si
  13.247 +                pushad
  13.248 +                mov     esi,[srcofs]
  13.249 +                mov     edi,[dstofs]
  13.250 +
  13.251 +			endif
  13.252 +
  13.253                  mov     ecx,[sz]
  13.254 +                jecxz   done
  13.255 +
  13.256 +		smsw	ax
  13.257 +		test	al,1
  13.258 +		jz	@@real_mode
  13.259 +; Note: bp points to std stack frame now. bp will be passed to
  13.260 +; pm routine. This allows params to be passed on stack
  13.261 +		extrn	do_memcpy_vcpi:near
  13.262 +                push    offset do_memcpy_vcpi
  13.263 +		extrn	call_pm_routine:near
  13.264 +                call    near call_pm_routine ; Call pm copy routine via vcpi pm
  13.265 +                pop     ax
  13.266 +		jmp	done
  13.267 +@@real_mode:
  13.268  		mov	dx,-1
  13.269  
  13.270 -	ifdef	keep_int15
  13.271 -                jecxz   godone
  13.272 -		test	[_vcpi],dl
  13.273 -		jne	with_movsw
  13.274 -
  13.275 -		push	ss
  13.276 -		pop	es
  13.277 -		inc	ecx
  13.278 -		shr	ecx,1
  13.279 -		mov	bx,9318h
  13.280 -clear:
  13.281 -		push	0
  13.282 -		dec	bl
  13.283 -		jnz	clear
  13.284 -  		xchg	eax,esi
  13.285 -  		mov	si,sp
  13.286 -		mov	[si+12h],eax
  13.287 -		mov	[si+1Ah],edi
  13.288 -		mov	[si+10h],dx
  13.289 -		mov	[si+18h],dx
  13.290 -		mov	edi,ecx
  13.291 -		mov	dh,93h
  13.292 -		xchg	bx,[si+14h]
  13.293 -		xchg	dx,[si+1Ch]
  13.294 -mvlp:
  13.295 -		mov	[si+14h],bl
  13.296 -		mov	[si+17h],bh
  13.297 -		mov	[si+1Ch],dl
  13.298 -		mov	[si+1Fh],dh
  13.299 -		xor	ecx,ecx
  13.300 -		mov	ch,80h
  13.301 -		sub	edi,ecx
  13.302 -		pushf
  13.303 -		jnc	domv
  13.304 -		add	ecx,edi
  13.305 -domv:
  13.306 -	;push	bx dx si edi
  13.307 -		mov	ah,87h
  13.308 -		int	15h
  13.309 -	;pop	edi si dx bx
  13.310 -		inc	bx
  13.311 -		inc	dx
  13.312 -		popf
  13.313 -		jnc	mvlp
  13.314 -		add	sp,30h
  13.315 -godone:
  13.316 -		jmp	done
  13.317 -	else
  13.318 -                jecxz   done
  13.319 -	endif
  13.320 -
  13.321  with_movsw:
  13.322 -                cld
  13.323                  cmp     esi,edi
  13.324                  jae     @@do_copy
  13.325                  add     esi,ecx         ;src<dst: we must do
  13.326 @@ -311,7 +357,6 @@
  13.327                  db      66h     ;operand width override for ecx
  13.328                  db      67h     ;address width override for esi/edi
  13.329              rep movsb
  13.330 -                cld
  13.331  
  13.332  ;****** Return to rm *******************************************
  13.333                  dec     ax              ;CR0_PE off
  13.334 @@ -322,10 +367,12 @@
  13.335  ;****** Return *************************************************
  13.336                  lgdt    [oldGDTR]
  13.337  done:
  13.338 -                cld
  13.339 -                pop     edi esi ds es
  13.340 +                popad
  13.341 +done16:
  13.342 +                pop     es ds
  13.343                  popf
  13.344 -                leave
  13.345 +		mov	sp,bp
  13.346 +		pop	bp
  13.347                  ret
  13.348  
  13.349  ;****** Const data *********************************************
  13.350 @@ -344,6 +391,39 @@
  13.351  
  13.352          endp    _memcpy32
  13.353  
  13.354 +		ifdef	NO386
  13.355 +        global  N_LXURSH@:near
  13.356 +        global  N_LXURSH@4:near
  13.357 +        proc    N_LXURSH@4 near
  13.358 +
  13.359 +		mov	cl,4
  13.360 +N_LXURSH@:
  13.361 +		mov	ch,0
  13.362 +@@loop:
  13.363 +		shr	dx,1
  13.364 +		rcr	ax,1
  13.365 +		loop	@@loop
  13.366 +		ret
  13.367 +
  13.368 +        endp    N_LXURSH@4
  13.369 +
  13.370 +        global  N_LXLSH@:near
  13.371 +        global  N_LXLSH@4:near
  13.372 +        proc    N_LXLSH@4 near
  13.373 +
  13.374 +		mov	cl,4
  13.375 +N_LXLSH@:
  13.376 +		mov	ch,0
  13.377 +@@loop:
  13.378 +		shl	ax,1
  13.379 +		rcl	dx,1
  13.380 +		loop	@@loop
  13.381 +		ret
  13.382 +
  13.383 +        endp    N_LXLSH@4
  13.384 +
  13.385 +		endif
  13.386 +
  13.387          ends    _TEXT
  13.388  
  13.389          end
    14.1 --- a/linld/stuff/src/TAZBOOT.CPP	Thu Dec 01 21:07:54 2016 +0200
    14.2 +++ b/linld/stuff/src/TAZBOOT.CPP	Fri Dec 02 12:37:59 2016 +0100
    14.3 @@ -7,21 +7,6 @@
    14.4  #include "common.h"
    14.5  #include "iso9660.h"
    14.6  
    14.7 -static void usage()
    14.8 -{
    14.9 -	puts("Usage: tazboot [[@commands]|[kernel=<bzimage>] \
   14.10 -[initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\
   14.11 -Defaults: tazboot kernel=bzImage auto\r\n\n\
   14.12 -Examples for tazboot.cmd:\r\n\n\
   14.13 -  bootfrom=\\isos\\slitaz-4.0.iso\r\n\
   14.14 -  kernel=boot/bzImage\r\n\
   14.15 -  initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\
   14.16 -  rw root=/dev/null vga=normal autologin\r\n\n\
   14.17 -  kernel=\\slitaz\\elks\r\n\
   14.18 -  root=/dev/bda1 ro\r\n");
   14.19 -	exit(1);
   14.20 -}
   14.21 -
   14.22  #define MAXINITRD 10
   14.23  static struct initrd_state {
   14.24  	u32 ofs[MAXINITRD];
   14.25 @@ -38,35 +23,38 @@
   14.26  	m->state++;
   14.27  }
   14.28  
   14.29 +static u32 isofilesize4round()
   14.30 +{
   14.31 +	return (isofilesize+3)&-4;
   14.32 +}
   14.33 +
   14.34  static void addinitrd()
   14.35  {
   14.36 -	if (initrd_state.cnt >= MAXINITRD) return;
   14.37 -	initrd_state.size[initrd_state.cnt] = isofilesize;
   14.38 -	initrd_state.ofs[initrd_state.cnt] = isofileofs;
   14.39 -	initrd_state.cnt++;
   14.40 -	initrd.size += (isofilesize+3)&-4;
   14.41 +	struct initrd_state *p = &initrd_state;
   14.42 +	if (p->cnt >= MAXINITRD) return;
   14.43 +	p->size[p->cnt] = isofilesize;
   14.44 +	p->ofs[p->cnt] = isofileofs;
   14.45 +	p->cnt++;
   14.46 +	initrd.size += isofilesize4round();
   14.47  }
   14.48  
   14.49  static void load_initrds()
   14.50  {
   14.51 -	if (!initrd.size) return;
   14.52 -	initrd.next_chunk = next_chunk;
   14.53 -	initrd.fd = isofd;
   14.54 -	initrd.state = 0;
   14.55 -	next_chunk(&initrd);
   14.56 +	struct image_himem *m = &initrd;
   14.57 +	if (!m->size) return;
   14.58 +	m->next_chunk = next_chunk;
   14.59 +	m->fd = isofd;
   14.60 +	m->state = 0;
   14.61 +	next_chunk(m);
   14.62  	load_initrd();
   14.63  }
   14.64  
   14.65 -static void pm_next_chunk(struct image_himem *m)
   14.66 +static char *isokernel()
   14.67  {
   14.68 -	if (!m->state++) m->chunk_size = m->size;
   14.69 -}
   14.70 -
   14.71 -static void isokernel()
   14.72 -{
   14.73 -	pm.size = (isofilesize+3)&-4;
   14.74 -	pm.fd = isofd;
   14.75 -	pm.next_chunk = pm_next_chunk;
   14.76 +	struct image_himem *m = &pm;
   14.77 +	m->chunk_size = m->size = isofilesize4round();
   14.78 +	m->fd = isofd;
   14.79 +	return load_kernel();
   14.80  }
   14.81  
   14.82  char _cmdline[256];
   14.83 @@ -91,8 +79,7 @@
   14.84  		    isoopen("bzImage") >= 0	|| 	// SliTaz
   14.85  		    isoopen("vmlinuz") >= 0	||	// misc
   14.86  		    (isoopen("linux") >= 0 && ++isknoppix)) {
   14.87 -			isokernel();
   14.88 -			magic = kver2ul(load_kernel());
   14.89 +			magic = kver2ul(isokernel());
   14.90  			break;
   14.91  		}
   14.92  	} while (isoopen("isolinux") >= 0);		// Knoppix
   14.93 @@ -122,9 +109,9 @@
   14.94  		if (isoopen(initrd) >= 0) {
   14.95  			addinitrd();
   14.96  		}
   14.97 -		if (*init && lseek(isofd, 20L, SEEK_SET) != -1 &&
   14.98 -		    read(isofd, &isofileofs, 4) == 4 &&
   14.99 -		    read(isofd, &magic, 4) == 4) {
  14.100 +		if (*init && lseek(isofd, 20L, SEEK_SET) != -1) {
  14.101 +			read(isofd, &isofileofs, 4);
  14.102 +			read(isofd, &magic, 4);
  14.103  			isofileofs &= 0xFFFFL;
  14.104  			isofilesize = magic & 0xFFFFL;
  14.105  			isofileofs -= 0xC0L + isofilesize;
  14.106 @@ -133,9 +120,9 @@
  14.107  		}
  14.108  		load_initrds();
  14.109  		strcat(_cmdline,init);
  14.110 -		strcat(_cmdline," mode=");
  14.111 +		strcatb(_cmdline,"mode=");
  14.112  		strcat(_cmdline,mode);
  14.113 -		strcat(_cmdline," magic=");
  14.114 +		strcatb(_cmdline,"magic=");
  14.115  		strcat(_cmdline,ultoa(magic));
  14.116  	}
  14.117  	if (isknoppix) {
  14.118 @@ -163,47 +150,69 @@
  14.119  	chdirname(*argv);
  14.120  	if (argc < 2) {
  14.121  dousage:
  14.122 -		usage();
  14.123 +		die("Usage: tazboot [[@commands]|[-f][kernel=<bzimage>] \
  14.124 +[initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\
  14.125 +Defaults: tazboot kernel=bzImage auto\r\n\n\
  14.126 +Examples for tazboot.cmd:\r\n\n\
  14.127 +  bootfrom=\\isos\\slitaz-4.0.iso\r\n\
  14.128 +  kernel=boot/bzImage\r\n\
  14.129 +  initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\
  14.130 +  rw root=/dev/null vga=normal autologin\r\n\n\
  14.131 +  kernel=\\slitaz\\elks\r\n\
  14.132 +  root=/dev/bda1 ro\r\n");
  14.133  	}
  14.134 -	for (int i=1; i < argc; i++) {
  14.135 -		char *s=argv[i];
  14.136 -		if (strhead(s,"kernel=") == 0)
  14.137 -			kernel_name = s + 7;
  14.138 -		if (strhead(s,"image=") == 0)
  14.139 -			kernel_name = s + 6;
  14.140 -		else if (strhead(s,"initrd=") == 0)
  14.141 -			initrd_name = s + 7;
  14.142 -		else if (strhead(s,"bootfrom=") == 0)
  14.143 -			iso = s + 9;
  14.144 -		else if (strhead(s,"iso=") == 0)
  14.145 -			iso = s + 4;
  14.146 +	for (int i=0;;) {
  14.147 +		char *s=*++argv;
  14.148 +		i++;
  14.149 +		if (!s) break;
  14.150 +		if (strhead(s,"kernel=") == 0) {
  14.151 +			s += 7;
  14.152 +	set_kernel:
  14.153 +			kernel_name = s;
  14.154 +		}
  14.155 +		else if (strhead(s,"image=") == 0) {
  14.156 +			s += 6;
  14.157 +			goto set_kernel;
  14.158 +		}
  14.159 +		else if (strhead(s,"initrd=") == 0) {
  14.160 +			s += 7;
  14.161 +			initrd_name = s;
  14.162 +		}
  14.163 +		else if (strhead(s,"bootfrom=") == 0) {
  14.164 +			s += 9;
  14.165 +	set_iso:
  14.166 +			iso = s;
  14.167 +		}
  14.168 +		else if (strhead(s,"iso=") == 0) {
  14.169 +			s += 4;
  14.170 +			goto set_iso;
  14.171 +		}
  14.172  		else if(strhead(s,"vga=") == 0) {
  14.173 -			s+=4;
  14.174 -			const char c = *s|0x20;
  14.175 -			if (c == 'a') vid_mode = -3;
  14.176 -			else if (c == 'e') vid_mode = -2;
  14.177 -			else if (c == 'n') vid_mode = -1;
  14.178 -			else vid_mode = strtol(s);
  14.179 +			s += 4;
  14.180 +			vid_mode = strtol(s);	// support normal, extended & ask
  14.181  		}
  14.182 -		else if(strhead(s,"-f") == 0) {
  14.183 +		else if((*(u16 *)s|0x2002) == 0x662F) { // -F /f
  14.184  			skip_xmmalloc++;
  14.185  		}
  14.186 +		else if(i == 1 && fileattr(s) != -1) {
  14.187 +			goto set_kernel;
  14.188 +		}
  14.189  		else {
  14.190  			if(strhead(s,"root=") == 0) {
  14.191 -				root_dev = strtol(s+5);
  14.192 +				s += 5;
  14.193 +				root_dev = strtol(s);
  14.194  			}
  14.195  			if(strhead(s,"mem=") == 0) {
  14.196 -				topmem = strtol(s+4);
  14.197 +				s += 4;
  14.198 +				topmem = strtol(s);
  14.199  			}
  14.200 -			if (_cmdline[0]) strcat(_cmdline," ");
  14.201 -			strcat(_cmdline,s);
  14.202 +			strcatb(_cmdline,*argv);
  14.203  		}
  14.204  	}
  14.205  	if (iso && isoreset(iso) >= 0) {
  14.206  		char *s = (char *) initrd_name;
  14.207  		if (isoopen((char *) kernel_name) >= 0) {
  14.208  			isokernel();
  14.209 -			load_kernel();
  14.210  		}
  14.211  		if (s) {
  14.212  			while (*s) {
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/linld/stuff/src/VCPI.ASM	Fri Dec 02 12:37:59 2016 +0100
    15.3 @@ -0,0 +1,457 @@
    15.4 +;***************************************************************
    15.5 +;****** This file is distributed under GPL
    15.6 +;***************************************************************
    15.7 +;VDPI init:
    15.8 +;Call  char* prepare_vcpi(void *pagebuf)  first to
    15.9 +;initialize paging tables needed for vm86.
   15.10 +;pagebuf needs to be 8k+4 bytes. Returns ptr to 1st unused byte.
   15.11 +;Then call  int get_vcpi_interface().  Returns 1 if ok, 0 if bad.
   15.12 +;
   15.13 +;VCPI use:
   15.14 +;u32* malloc_vcpi(u32 size)  - source in HIMEM.CPP
   15.15 +;  Returns ptr to mallocated zero-terminated list of 4k page addrs
   15.16 +;  Addresses are sorted in ascending order
   15.17 +;  Never fails (will die if not enough mem)
   15.18 +;void read2vcpi(int fd, u32* vp, u32 size,
   15.19 +;void* xfer_buf, u16 xfer_size)  - source in HIMEM.CPP
   15.20 +;  Reads opened fd data into malloc_vcpi'ed memory
   15.21 +;  Dies if file isn't exactly 'size' bytes long
   15.22 +;  Needs intermediate buffer of exactly Nx4k bytes
   15.23 +;void memcpy_vcpi(u32 dstofs,u16 srcseg,u32 srcofs)
   15.24 +;  copies 4k from conventional memory to VCPI
   15.25 +;void _vm2rm()
   15.26 +;  switches you from vm86 to plain real mode
   15.27 +
   15.28 +
   15.29 +                ideal
   15.30 +                %crefref
   15.31 +                %noincl
   15.32 +                %nomacs
   15.33 +                p386
   15.34 +
   15.35 +;****** Stuff for declaring descriptors
   15.36 +struc   descr
   15.37 +limit           dw    ?
   15.38 +base0           dw    ?
   15.39 +base16          db    ?
   15.40 +type            db    ?
   15.41 +limit16         db    ?
   15.42 +base24          db    ?
   15.43 +ends    descr
   15.44 +macro   descriptor name,typ,plevel,present,limit,gran,base
   15.45 +      ;;name    descr <limit and 0ffffh,base and 0ffffh,low (base shr 16),typ or plevel or present,(limit shr 16) or gran,high (base shr 16)>
   15.46 +        name    descr <limit and 0ffffh,base           ,0                ,typ or plevel or present,(limit shr 16) or gran,0                 >
   15.47 +endm
   15.48 +; decriptor types (bit0..4 of descr.type )
   15.49 +tss386_avail    = 09h
   15.50 +data_seg        = 00010000b   ; data segment
   15.51 +  expand_down   = 00000100b   ; =1 limit counts down from base
   15.52 +  writable      = 00000010b   ; =1 if write access allowed to data segment
   15.53 +code_seg        = 00011000b   ; code segment
   15.54 +  conforming    = 00000100b   ; =1 code can be accesses and executed at any PL
   15.55 +  readable      = 00000010b   ; =1 if code also can be read (cannot be ovwritten)
   15.56 +; privilege levels (bit5..6 of descr.type )
   15.57 +priv0           = 00000000b
   15.58 +priv1           = 00100000b
   15.59 +priv2           = 01000000b
   15.60 +priv3           = 01100000b
   15.61 +; segment present bit (bit7 of descr.type )
   15.62 +is_present      = 10000000b
   15.63 +not_present     = 00000000b
   15.64 +;definition of granularity ( bits6..7 in descr.limit16 )
   15.65 +gran_byte       = 00000000b
   15.66 +gran_page       = 10000000b  ; 4k granularity
   15.67 +use_16          = 00000000b
   15.68 +use_32          = 01000000b
   15.69 +
   15.70 +;****** rm32,imm16 helpers
   15.71 +macro   movzx_e rm,i
   15.72 +        db      66h
   15.73 +        mov     rm,i
   15.74 +        dw      0
   15.75 +endm
   15.76 +macro   addzx_e rm,i
   15.77 +        db      66h
   15.78 +        add     rm,i
   15.79 +        dw      0
   15.80 +endm
   15.81 +
   15.82 +
   15.83 +        group   DGROUP  _TEXT,_DATA
   15.84 +        assume  cs:DGROUP,ds:DGROUP
   15.85 +
   15.86 +        segment _DATA byte public use16 'DATA'
   15.87 +
   15.88 +tss             dd      0,0     ;enough, we'll never use it anyway
   15.89 +
   15.90 +label   gdt     byte
   15.91 +gdt_null        descr   <?>     ;0000
   15.92 +gdt_vcpi        descr   <?>     ;0008
   15.93 +gdt_vcpi2       descr   <?>     ;0010
   15.94 +gdt_vcpi3       descr   <?>     ;0018
   15.95 +descriptor      gdt_abs ,(data_seg+writable),priv0,is_present,0fffffh,(gran_page+use_32),0
   15.96 +;Note: code/data segs must be flagged use16 (i.e. use ip/sp, not eip/esp)
   15.97 +;Note: base addrs will be fixed up in prepare_vcpi()
   15.98 +descriptor      gdt_code,(code_seg+readable),priv0,is_present,0fffffh,(gran_page+use_16),0
   15.99 +descriptor      gdt_data,(data_seg+writable),priv0,is_present,0fffffh,(gran_page+use_16),0
  15.100 +descriptor      gdt_tss ,tss386_avail       ,priv0,is_present,0ffh   ,gran_byte         ,<offset tss>
  15.101 +SEL_VCPI        = (gdt_vcpi - gdt_null)
  15.102 +SEL_TSS         = (gdt_tss  - gdt_null)
  15.103 +SEL_ABS         = (gdt_abs  - gdt_null)
  15.104 +SEL_CODE        = (gdt_code - gdt_null)
  15.105 +SEL_DATA        = (gdt_data - gdt_null)
  15.106 +
  15.107 +label   gdtr    pword
  15.108 +gdt_lim         dw      0ffffh
  15.109 +gdt_base        dw      offset gdt,0
  15.110 +label   idtr    pword
  15.111 +idt_lim         dw      03ffh   ;we won't enable ints,
  15.112 +idt_base        dd      0       ;  so let's leave it the same as for rm
  15.113 +
  15.114 +;Note: layout dictated by vcpi api, don't rearrange!
  15.115 +label sw2pm_params byte
  15.116 +;Note: base addrs will be fixed up in prepare_vcpi()
  15.117 +sw2pm_cr3       dd      ?
  15.118 +sw2pm_gdtr_ptr  dw      offset gdtr,0
  15.119 +sw2pm_idtr_ptr  dw      offset idtr,0
  15.120 +sw2pm_ldtr      dw      0       ;we don't need it
  15.121 +sw2pm_tr        dw      SEL_TSS ;vcpi thinks we need it... can't set to 0
  15.122 +sw2pm_jumpaddr  dd      ?
  15.123 +                dw      SEL_CODE
  15.124 +
  15.125 +;Pagedir/page0 addrs: linear, seg:0 and cs:ofs
  15.126 +pagedir_laddr   dd      ?
  15.127 +page0_laddr     dd      ?
  15.128 +;;pagedir_seg     dw      ?
  15.129 +;;page0_seg       dw      ?
  15.130 +pagedir_ofs     dw      ?
  15.131 +page0_ofs       dw      ?
  15.132 +
  15.133 +vcpi_pm_entry   dd      ?
  15.134 +                dw      SEL_VCPI
  15.135 +
  15.136 +label   saved_ss_sp dword
  15.137 +saved_sp        dw      ?
  15.138 +saved_ss        dw      ?
  15.139 +
  15.140 +
  15.141 +        ends    _DATA
  15.142 +
  15.143 +
  15.144 +        segment _TEXT byte public use16 'CODE'
  15.145 +
  15.146 +;***************************************************************
  15.147 +;char* prepare_vcpi(void *pagebuf);
  15.148 +;****** Return: AX=>first unused byte in pagebuf
  15.149 +;****** Uses:   Flags
  15.150 +;***************************************************************
  15.151 +        global  _prepare_vcpi:near
  15.152 +        global  prepare_vcpi:near
  15.153 +        proc    _prepare_vcpi near
  15.154 +
  15.155 +                ;pop     ax
  15.156 +                ;pop     bx		;pgbuf
  15.157 +                ;push    bx
  15.158 +                ;push    ax
  15.159 +prepare_vcpi:
  15.160 +                ;push    esi
  15.161 +                ;push    es
  15.162 +
  15.163 +;Calculate pagedir/page0 addrs, initialize cr3 and pagedir[0]
  15.164 +                xor     eax,eax
  15.165 +;    heap_top = prepare_vcpi(malloc_or_die(8*1024+4)); 
  15.166 +		mov	cx,8*1024+4
  15.167 +                extrn   malloc_or_die:near
  15.168 +		call	malloc_or_die
  15.169 +
  15.170 +		mov	cl,4
  15.171 +                mov     edx,cs
  15.172 +                shl     edx,cl          ;ebx = linear addr of CS
  15.173 +                mov     bx, offset page0_laddr
  15.174 +; Fix up base of some gdt descriptors
  15.175 +; Note: 'add [dword xx.base0],edx' actually updates 24 bit quantity!
  15.176 +; Do NOT replace with mov!
  15.177 +                add     [dword bx+gdt_base-page0_laddr],edx
  15.178 +                add     [dword bx+sw2pm_gdtr_ptr-page0_laddr],edx
  15.179 +                add     [dword bx+sw2pm_idtr_ptr-page0_laddr],edx
  15.180 +                add     [dword bx+(gdt_code.base0)-page0_laddr],edx
  15.181 +                add     [dword bx+(gdt_data.base0)-page0_laddr],edx
  15.182 +                add     [dword bx+(gdt_tss.base0)-page0_laddr],edx
  15.183 +                add     eax,edx
  15.184 +                mov     esi,0FFFh
  15.185 +                add     eax,esi
  15.186 +		inc	si		;esi=00001000h
  15.187 +
  15.188 +                shr     eax,cl
  15.189 +                mov     al,0   ;eax = 4k aligned linear addr of pagebuf
  15.190 +                mov     es,ax           ;es:0->page0,es:1000h->pagedir
  15.191 +                shl     eax,cl          ;eax=page0 linear addr
  15.192 +                mov     [bx+page0_laddr-page0_laddr],eax
  15.193 +                mov     al,3            ;add present+writable bits
  15.194 +                mov     [es:si],eax     ;stuff it into pagedir[0]
  15.195 +
  15.196 +                add     eax,esi
  15.197 +		mov	al,0
  15.198 +                mov     [bx+pagedir_laddr-page0_laddr],eax
  15.199 +                        ;page directory will use only one entry (4 bytes):
  15.200 +                        ;cr3 => pagedir => page0  => ########
  15.201 +                        ;      (1 entry)  (1024   => #  4M  #
  15.202 +                        ;                 entries)=> # page #
  15.203 +                        ;                         => ########
  15.204 +                mov     [bx+sw2pm_cr3-page0_laddr],eax
  15.205 +                sub     eax,edx         ;ax = offset in CS of pagedir
  15.206 +                mov     [bx+pagedir_ofs-page0_laddr],ax
  15.207 +                sub     ax,si   ;ax-=1000
  15.208 +                mov     [bx+page0_ofs-page0_laddr],ax
  15.209 +; Return
  15.210 +                ;pop     es
  15.211 +                ;pop     esi
  15.212 +                add     ax,1004h
  15.213 +		extrn	_heap_top:word
  15.214 +		mov	[_heap_top],ax
  15.215 +                ;ret
  15.216 +
  15.217 +        endp    _prepare_vcpi
  15.218 +
  15.219 +
  15.220 +;***************************************************************
  15.221 +;int get_vcpi_interface();
  15.222 +;****** Return: AX=1 - page mapping for low 640k is 1:1
  15.223 +;******         AX=0 - otherwise (it's bad)
  15.224 +;****** Uses:   Flags
  15.225 +;***************************************************************
  15.226 +        global  _get_vcpi_interface:near
  15.227 +        proc    _get_vcpi_interface near
  15.228 +
  15.229 +                ;push    si di
  15.230 +
  15.231 +; Get and save VCPI pm interface
  15.232 +                mov     si,offset gdt_vcpi      ;DS:DI => 3 GDT entries for VCPI
  15.233 +                mov     di,[si+page0_ofs-gdt_vcpi]          ;ES:DI => page0
  15.234 +                push    ds
  15.235 +                pop     es
  15.236 +                mov     ax,0DE01h               ;get vcpi pm interface
  15.237 +                int     67h
  15.238 +                mov     [vcpi_pm_entry],ebx
  15.239 +
  15.240 +; Check that mapping for low 640k is 1:1
  15.241 +                mov     si,[page0_ofs]
  15.242 +                xor     bx,bx
  15.243 +                cld
  15.244 +@@map_chk:
  15.245 +                lodsd
  15.246 +                shr     eax,12
  15.247 +                cmp     ax,bx
  15.248 +                stc
  15.249 +                jne     @@bad
  15.250 +                inc     bx
  15.251 +                cmp     ax,((640*1024) shr 12)-1
  15.252 +                jne     @@map_chk
  15.253 +; Return
  15.254 +@@bad:
  15.255 +                sbb     ax,ax
  15.256 +                inc	ax			; update Z
  15.257 +                ;pop     di si
  15.258 +                ret
  15.259 +        endp    _get_vcpi_interface
  15.260 +
  15.261 +
  15.262 +;***************************************************************
  15.263 +;void memcpy_vcpi(u32 dstofs,u16 srcseg,u32 srcofs);
  15.264 +;***************************************************************
  15.265 +;****** Copies PAGE_SIZE bytes
  15.266 +;****** Uses:   Flags
  15.267 +;***************************************************************
  15.268 +        global  call_pm_routine:near
  15.269 +        proc    call_pm_routine near
  15.270 +
  15.271 +              arg     dstofs  :dword, \
  15.272 +                      srcseg  :word,  \
  15.273 +                      srcofs  :dword  = PARAM_SIZE
  15.274 +
  15.275 +struc   pm_regs
  15.276 +$$retaddr       dw      ?
  15.277 +$$f             dw      ?
  15.278 +$$edi           dd      ?
  15.279 +$$esi           dd      ?
  15.280 +$$ebp           dd      ?
  15.281 +$$esp           dd      ?
  15.282 +$$ebx           dd      ?
  15.283 +$$edx           dd      ?
  15.284 +$$ecx           dd      ?
  15.285 +$$eax           dd      ?
  15.286 +ends
  15.287 +
  15.288 +;***************************************************************
  15.289 +;****** Helper: goes into 16bit pm and calls routine (addr on stk)
  15.290 +;***************************************************************
  15.291 +                mov     bp,sp           ; ss:bp => struct pm_regs
  15.292 +
  15.293 +                xor     ax,ax           ; IRET stack for return to vm
  15.294 +                push    ax gs           ;   (9 dwords)
  15.295 +                push    ax fs           ;
  15.296 +                push    ax ds           ;
  15.297 +                push    ax es           ;
  15.298 +                push    ax ss           ;
  15.299 +                push    ebp             ; esp
  15.300 +                pushfd                  ; eflags: IF saved here
  15.301 +                push    ax cs           ;
  15.302 +                push    ax              ;\eip
  15.303 +                push    offset @@vm_ret ;/
  15.304 +
  15.305 +                cli
  15.306 +              ;;mov     [saved_xx],xx   ;use if your vcpi trashes bp/etc
  15.307 +
  15.308 +                movzx_e <[word sw2pm_jumpaddr]>,<offset @@pm_entry>
  15.309 +               ;mov     [word sw2pm_jumpaddr+4],SEL_CODE
  15.310 +                mov     esi,cs
  15.311 +                shl     esi,4
  15.312 +                addzx_e si,<offset sw2pm_params>
  15.313 +                mov     ax,0DE0Ch       ; vcpi: switch to pm
  15.314 +                int     67h
  15.315 +@@pm_entry:
  15.316 +; Now we are in 16-bit protected mode
  15.317 +                mov     ax,SEL_DATA
  15.318 +                mov     ss,ax
  15.319 +              ;;mov     ds,ax
  15.320 +              ;;mov     es,ax
  15.321 +              ;;mov     fs,ax
  15.322 +              ;;mov     gs,ax
  15.323 +                assume  nothing
  15.324 +                assume  cs:DGROUP
  15.325 +
  15.326 +              ;;mov     xx,[saved_xx]   ;use if your vcpi trashes bp/etc
  15.327 +                lea     sp,[bp-9*4]     ;else we can do this trick with bp
  15.328 +
  15.329 +; Call the routine (bp points to params on stack if any)
  15.330 +                mov     ax,[(pm_regs bp).$$f]   ; ss:bp => struct pm_regs
  15.331 +                mov     bp,[word (pm_regs bp).$$ebp]    ;ss:bp => params
  15.332 +                call    ax
  15.333 +
  15.334 +; Ok, let's return to vm
  15.335 +                cli     ; to be safe
  15.336 +                clts    ;
  15.337 +                push    SEL_ABS         ; vcpi wants ds=all_addrspace
  15.338 +                pop     ds              ;
  15.339 +                mov     ax,0DE0Ch       ; maybe we need whole eax?
  15.340 +                call    [pword cs:vcpi_pm_entry]
  15.341 +@@vm_ret:
  15.342 +; Now we are in vm86 mode. Sregs, esp, eflags (IF) restored from IRET stack
  15.343 +                ret
  15.344 +
  15.345 +;***************************************************************
  15.346 +;****** Helper: This is where real copy is done
  15.347 +;***************************************************************
  15.348 +	global	do_memcpy_vcpi:near
  15.349 +label   do_memcpy_vcpi near
  15.350 +
  15.351 +; Note: ss:bp => params
  15.352 +; Move data
  15.353 +                mov     cx,SEL_ABS
  15.354 +                mov     ds,cx
  15.355 +                mov     es,cx
  15.356 +                assume  nothing
  15.357 +                assume  cs:DGROUP
  15.358 +
  15.359 +        ; Set up target addr:
  15.360 +        ; replace page mapping for page at 0 so
  15.361 +        ; that it points to dstofs
  15.362 +                mov     esi,[cs:page0_laddr]
  15.363 +                mov     eax,[dstofs]
  15.364 +                mov     al,03h          ; writeable, present
  15.365 +                xchg    [esi],eax       ; replace page0[0]
  15.366 +               ;push    eax             ;X we'll need to restore mapping...
  15.367 +                mov     ecx,cr3         ; reload TLB cache
  15.368 +                mov     cr3,ecx         ;
  15.369 +                xor     edi,edi         ;es:edi => remapped page
  15.370 +
  15.371 +        ; Set up source addr
  15.372 +                mov     esi,[srcofs]
  15.373 +
  15.374 +        ; Do copying
  15.375 +                mov     ecx,4096/2
  15.376 +                cld
  15.377 +;;              cmp     esi,edi
  15.378 +;;              jae     @@do_copy
  15.379 +;;              add     esi,ecx         ;src<dst: we must do
  15.380 +;;              dec     esi             ;  copy backwards to avoid
  15.381 +;;              add     edi,ecx         ;  overwrite bug
  15.382 +;;              dec     edi             ;
  15.383 +;;              std                     ;
  15.384 +;;@@do_copy:
  15.385 +                db      67h     ;address width override for esi/edi
  15.386 +            rep movsw
  15.387 +;;              cld
  15.388 +
  15.389 +        ; Restore page mapping for page at 0
  15.390 +               ;pop     eax             ;X
  15.391 +                mov     esi,[cs:page0_laddr]
  15.392 +                mov     [esi],eax       ; restore page0[0]
  15.393 +                mov     ecx,cr3         ; reload TLB cache
  15.394 +                mov     cr3,ecx         ;
  15.395 +; Return
  15.396 +                ret
  15.397 +
  15.398 +        endp    call_pm_routine
  15.399 +                assume  cs:DGROUP,ds:DGROUP
  15.400 +
  15.401 +
  15.402 +;***************************************************************
  15.403 +;void _vm2rm();
  15.404 +;***************************************************************
  15.405 +;****** Uses:   Flags
  15.406 +;***************************************************************
  15.407 +        global  _vm2rm:near
  15.408 +        proc    _vm2rm near
  15.409 +
  15.410 +                push	esi
  15.411 +              ;;pushf
  15.412 +              ;;cli
  15.413 +              ;;pushad
  15.414 +                push    cs      ;*
  15.415 +                push    ds
  15.416 +                mov     [saved_ss],ss
  15.417 +                mov     [saved_sp],sp
  15.418 +
  15.419 +                movzx_e <[word sw2pm_jumpaddr]>,<offset @@pm_entry>
  15.420 +               ;mov     [word sw2pm_jumpaddr+4],SEL_CODE
  15.421 +                mov     esi,cs
  15.422 +                shl     esi,4
  15.423 +                addzx_e si,<offset sw2pm_params>
  15.424 +                mov     ax,0DE0Ch       ; vcpi: switch to pm
  15.425 +                int     67h
  15.426 +; Now we are in 16-bit protected mode
  15.427 +@@pm_entry:
  15.428 +                mov     ax,SEL_DATA     ; load data sregs with limit >=64k
  15.429 +                mov     ss,ax           ;   or you may get limit violations
  15.430 +                mov     ds,ax           ;   later in rm
  15.431 +                mov     es,ax           ;   (actually I prefer 4gig limits :-)
  15.432 +                mov     fs,ax           ;
  15.433 +                mov     gs,ax           ;
  15.434 +
  15.435 +; Black magic here
  15.436 +                mov     eax,cr0
  15.437 +                and     eax,7ffffffeh   ; clear PG,P bits
  15.438 +                mov     cr0,eax         ; look mommy, we're in rm now!
  15.439 +              ;;jmp     short $+2
  15.440 +              ;;xor     eax,eax
  15.441 +                mov     cr3,eax         ; flush TLB cache
  15.442 +
  15.443 +; Now we are in rm, but not yet: have to restore sregs:
  15.444 +                lss     sp,[saved_ss_sp]; SS
  15.445 +                pop     ds              ; DS
  15.446 +               ;push    cs      ;* done earlier
  15.447 +                push    offset @@next
  15.448 +                retf                    ; CS
  15.449 +@@next:
  15.450 +              ;;popad
  15.451 +              ;;popf
  15.452 +                pop	esi
  15.453 +                ret             ; We don't care much about rest (ES/FS/GS)
  15.454 +        endp    _vm2rm
  15.455 +
  15.456 +        ends    _TEXT
  15.457 +
  15.458 +        end
  15.459 +
  15.460 +;###### END OF FILE ############################################
    16.1 --- a/linld/stuff/src/XMM.ASM	Thu Dec 01 21:07:54 2016 +0200
    16.2 +++ b/linld/stuff/src/XMM.ASM	Fri Dec 02 12:37:59 2016 +0100
    16.3 @@ -60,26 +60,44 @@
    16.4  @@gotit:
    16.5  		call	[xmm_handler]
    16.6                  ret
    16.7 +xmm_fail:
    16.8 +                xor     ax,ax
    16.9 +                cwd
   16.10 +                retf
   16.11 +
   16.12          endp    xmm_driver
   16.13  
   16.14  
   16.15  ;***************************************************************
   16.16 -;u32 xmm_alloc(void* drv, u32 size)
   16.17 +;void xmm_alloc(struct image_himem *m)
   16.18 +;struct image_himem {
   16.19 +; 0    int fd;
   16.20 +; 2    u32 fallback;
   16.21 +; 6    u32 size;
   16.22 +;10    u32 remaining;
   16.23 +;14    u32 buf;
   16.24 +;18    u32 *bufv;
   16.25 +;20    char *errmsg;
   16.26 +;22    u32 chunk_size;
   16.27 +;26    void (*next_chunk)(struct image_himem *);
   16.28 +;28    u16 state;
   16.29 +;30    u16 fd2close;
   16.30 +;};
   16.31  ;***************************************************************
   16.32          global  _xmm_alloc:near
   16.33          proc    _xmm_alloc near
   16.34  
   16.35 +                pop     ax
   16.36                  pop     bx
   16.37 +                push    bx
   16.38 +                push    ax
   16.39  		ifndef	NO386
   16.40 -                pop     edx
   16.41 -                push    edx
   16.42 +		mov	edx,[bx+6]		; m->size
   16.43                  dec     edx
   16.44                  shr     edx,10          ; to Kb
   16.45  		else
   16.46 -                pop     ax
   16.47 -                pop     dx
   16.48 -                push    dx
   16.49 -                push    ax
   16.50 +		mov	ax,[bx+6]		; lo m->size
   16.51 +		mov	dx,[bx+8]		; hi m->size
   16.52  		sub	ax,1
   16.53  		sbb	dx,0
   16.54  		mov	cx,10
   16.55 @@ -89,25 +107,25 @@
   16.56  		loop	@@tokblp
   16.57  		endif
   16.58                  inc     dx
   16.59 -                push    cs
   16.60 -                push    bx
   16.61 +		push	bx
   16.62                  mov     ah,09h          ;allocate blk
   16.63                  call    xmm_driver      ;
   16.64                  dec     ax
   16.65 -                jnz     @@err
   16.66 +                jnz     @@goerr
   16.67                                          ;now: dx=handle of the blk
   16.68                  mov     ah,0Ch          ;lock blk
   16.69                  call    xmm_driver      ;
   16.70                  dec     ax
   16.71                                          ;now: dx:bx=addr of blk
   16.72                  xchg    ax,bx
   16.73 -                jz      @@ok
   16.74 +@@goerr:
   16.75 +		pop	bx
   16.76 +                jnz     @@err
   16.77 +		mov	[bx+14],ax	; lo m->buf
   16.78 +		mov	[bx+16],dx	; hi m->buf
   16.79  @@err:
   16.80 -xmm_fail:
   16.81 -                xor     ax,ax
   16.82 -                cwd
   16.83 -@@ok:
   16.84 -                retf
   16.85 +                ret
   16.86 +
   16.87          endp    _xmm_alloc
   16.88  
   16.89          ends    _TEXT
    17.1 --- a/linld/stuff/src/_BEG.ASM	Thu Dec 01 21:07:54 2016 +0200
    17.2 +++ b/linld/stuff/src/_BEG.ASM	Fri Dec 02 12:37:59 2016 +0100
    17.3 @@ -109,16 +109,9 @@
    17.4  ;***************************************************************
    17.5                  extrn   _main:near
    17.6                  call    _main
    17.7 -                push	ax
    17.8 -                push	ax
    17.9 +
   17.10  ;***************************************************************
   17.11 -;void exit(int n);
   17.12 -;***************************************************************
   17.13 -	        global  _exit:near
   17.14  	        global  exit:near
   17.15 -_exit:
   17.16 -		pop	bx			;caller return address
   17.17 -                pop	ax			; n
   17.18  exit:
   17.19                  mov	ah,4Ch
   17.20                  int	21h