wok rev 19571

linld: large image support with VCPI
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Dec 22 21:06:17 2016 +0100 (2016-12-22)
parents bb506432c82c
children 26788507533b
files 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/HIMEM.CPP linld/stuff/src/ISO9660.CPP linld/stuff/src/ISO9660.H linld/stuff/src/JUMP.ASM linld/stuff/src/LINLD.CPP linld/stuff/src/LOAD.CPP linld/stuff/src/MEMCPY32.ASM linld/stuff/src/MEMTOP.ASM linld/stuff/src/TAZBOOT.CPP linld/stuff/src/VCPI.ASM linld/stuff/src/_BEG.ASM
line diff
     1.1 --- a/linld/stuff/src/!COMPILE.BAT	Thu Dec 22 20:43:12 2016 +0100
     1.2 +++ b/linld/stuff/src/!COMPILE.BAT	Thu Dec 22 21:06:17 2016 +0100
     1.3 @@ -3,14 +3,17 @@
     1.4  tasm /h > helptasm.log
     1.5  bcc > helpbcc.log
     1.6  tlink > helptlink.log
     1.7 -tasm /la /m *.asm > asm.log
     1.8 +rem tasm /la /m *.asm > asm.log
     1.9 +tasm /la /m /dLARGE_IMAGES *.asm > asm.log
    1.10  rem @pause
    1.11 -bcc @bccopt.opt -S -mt *.cpp
    1.12 +rem bcc @bccopt.opt -S -mt *.cpp
    1.13 +bcc @bccopt.opt -S -mt -DLARGE_IMAGES *.cpp
    1.14  tasm /l /m load.asm
    1.15  tasm /l /m himem.asm
    1.16  tasm /l /m linld.asm
    1.17  tasm /l /m iso9660.asm
    1.18 -bcc @bccopt.opt -c -mt *.cpp > cpp.log
    1.19 +rem bcc @bccopt.opt -c -mt *.cpp > cpp.log
    1.20 +bcc @bccopt.opt -c -mt -DLARGE_IMAGES *.cpp > cpp.log
    1.21  rem @pause
    1.22  tlink /m /s /t @link.cmd > lnk.log
    1.23  rem @pause
     2.1 --- a/linld/stuff/src/!COMPILEX.BAT	Thu Dec 22 20:43:12 2016 +0100
     2.2 +++ b/linld/stuff/src/!COMPILEX.BAT	Thu Dec 22 21:06:17 2016 +0100
     2.3 @@ -1,13 +1,16 @@
     2.4  path ..\BC31;%PATH%
     2.5  call !clean.bat
     2.6 -tasm /la /m /dNO386 *.asm > asm.log
     2.7 +rem tasm /la /m /dNO386 *.asm > asm.log
     2.8 +tasm /la /m /dNO386 /dLARGE_IMAGES *.asm > asm.log
     2.9  rem @pause
    2.10 -bcc @bccopt.opt -S -mt *.cpp
    2.11 +rem bcc @bccopt.opt -S -mt *.cpp
    2.12 +bcc @bccopt.opt -S -mt -DLARGE_IMAGES *.cpp
    2.13  tasm /l /m load.asm
    2.14  tasm /l /m himem.asm
    2.15  tasm /l /m tazboot.asm
    2.16  tasm /l /m iso9660.asm
    2.17 -bcc @bccopt.opt -c -mt *.cpp > cpp.log
    2.18 +rem bcc @bccopt.opt -c -mt *.cpp > cpp.log
    2.19 +bcc @bccopt.opt -c -mt -DLARGE_IMAGES *.cpp > cpp.log
    2.20  rem @pause
    2.21  tlink /m /s /t @linkx.cmd > lnk.log
    2.22  rem @pause
     3.1 --- a/linld/stuff/src/COMMON.H	Thu Dec 22 20:43:12 2016 +0100
     3.2 +++ b/linld/stuff/src/COMMON.H	Thu Dec 22 21:06:17 2016 +0100
     3.3 @@ -49,6 +49,19 @@
     3.4      u16 fd2close;
     3.5  } pm, initrd;
     3.6  
     3.7 +extern "C" void memcpy_image(struct image_himem *m);
     3.8 +extern "C" void storepage(u32 *dst, u16 src);
     3.9 +#ifdef LARGE_IMAGES
    3.10 +extern "C" void reset_bufv(unsigned long *p);
    3.11 +extern "C" unsigned long* prev_bufv();
    3.12 +extern "C" unsigned long* next_bufv();
    3.13 +#define next(p)	 p = next_bufv()
    3.14 +#define prev(p)	 p = prev_bufv()
    3.15 +#else
    3.16 +#define reset_bufv(p)
    3.17 +#define next(p)	 ++p
    3.18 +#define prev(p)	 --p
    3.19 +#endif
    3.20  extern char vcpi;
    3.21  extern const char* kernel_name;
    3.22  extern const char* initrd_name;
    3.23 @@ -57,8 +70,8 @@
    3.24  extern u16 vid_mode;
    3.25  // External asm helpers
    3.26  extern "C" void memcpy32(u32, u16,u32, u32);
    3.27 -extern "C" void rmcpy(void* rmbuf, u16 rmsize);
    3.28 -extern "C" void set_sregs_jump_seg_ofs(u32 csip, u32 sssp);
    3.29 +extern "C" void rmcpy();
    3.30 +extern "C" void set_sregs_jump_seg_ofs(u32 csip);
    3.31  extern "C" void xmm_alloc(struct image_himem *m);
    3.32  extern u32 topmem;
    3.33  extern "C" u32 memtopz();
     4.1 --- a/linld/stuff/src/CRTL.ASM	Thu Dec 22 20:43:12 2016 +0100
     4.2 +++ b/linld/stuff/src/CRTL.ASM	Thu Dec 22 21:06:17 2016 +0100
     4.3 @@ -18,7 +18,7 @@
     4.4  msg_hang	db      "High mem corrupted - not exiting to DOS"
     4.5  msg_crlf	db	13,10,0
     4.6  vcpi_alloc_err	db	"vcpi "
     4.7 -msg_malloc      db      "malloc() failure",0
     4.8 +msg_malloc      db      "malloc failure",0
     4.9  
    4.10          ends    _DATA
    4.11  
    4.12 @@ -28,6 +28,9 @@
    4.13  _no_exit	db	?
    4.14  filecnt		db	?		; in fact 0 minus file count...
    4.15  nextfilename	dw	?
    4.16 +	ifdef	LARGE_IMAGES
    4.17 +curdata		dw	?
    4.18 +	endif
    4.19  
    4.20          ends    _BSS
    4.21  
    4.22 @@ -112,13 +115,13 @@
    4.23  		push	cx
    4.24  		push	ax
    4.25          global  malloc:near			; malloc(cx)
    4.26 -malloc:
    4.27 +malloc:						; keep CX, use AX,BX
    4.28  		mov	ax,[_heap_top]
    4.29 +		mov	bx,-1400h		; MIN_STACK=_1k+PAGE_SIZE
    4.30 +		add	bx,sp
    4.31 +		sub	bx,ax			; can't overflow
    4.32 +		cmp	bx,cx
    4.33  		mov	bx,offset msg_malloc
    4.34 -		mov	dx,-1400h		; MIN_STACK=_1k+PAGE_SIZE
    4.35 -		add	dx,sp
    4.36 -		sub	dx,ax			; can't overflow
    4.37 -		cmp	dx,cx
    4.38  		jb	puts
    4.39  		add	[_heap_top],cx		; _BEG has zero'd heap
    4.40  		;mov	bx,ax
    4.41 @@ -286,38 +289,32 @@
    4.42  
    4.43  
    4.44  ;***************************************************************
    4.45 -;long lseek(int fd, long sz, int dir);
    4.46 +;long lseekset(int fd, long sz);
    4.47  ;***************************************************************
    4.48 -        global  _lseek:near
    4.49 -        proc    _lseek near
    4.50 +        global  _lseekset:near
    4.51 +        proc    _lseekset near
    4.52  
    4.53 -		ifndef	NO386
    4.54  		pop	ax			;caller return address
    4.55                  pop	bx			; fd
    4.56 -                pop	ecx			; sz
    4.57 -                pop	dx			; dir
    4.58 +                pop	dx			; sz lo
    4.59 +                pop	cx			; sz hi
    4.60 +                push	cx
    4.61                  push	dx
    4.62 -                push	ecx
    4.63                  push	bx
    4.64                  push	ax
    4.65 -		else
    4.66 -		mov	bx,sp
    4.67 -		mov	dx,[bx+8]
    4.68 -		mov	cx,[bx+6]
    4.69 -		mov	ax,[bx+4]
    4.70 -		mov	bx,[bx+2]
    4.71 -		endif
    4.72 -lseek:
    4.73 -		xchg	ax,dx			; dir
    4.74 -                mov	ah,42h
    4.75 -		ifndef	NO386
    4.76 -                push	ecx
    4.77 -                pop	dx
    4.78 -                pop	cx
    4.79 -		endif
    4.80 +        global  lseekset:near
    4.81 +lseekset:
    4.82 +		clc
    4.83 +        global  rewind:near
    4.84 +rewind:						; rewind(bx,C=1)
    4.85 +		mov	ax,4200h
    4.86 +		jnc	dos
    4.87 +lseek0:						; lseek0(bx,ax=dir)
    4.88 +		cwd
    4.89 +		xor	cx,cx
    4.90  		jmp	dos
    4.91  
    4.92 -        endp    _lseek
    4.93 +        endp    _lseekset
    4.94  
    4.95  
    4.96  ;***************************************************************
    4.97 @@ -444,6 +441,16 @@
    4.98  fd2close	dw	?	;30    u16 fd2close;
    4.99  ends				;};
   4.100  
   4.101 +	ifdef	LARGE_IMAGES
   4.102 +struc   data_himem			;struct data_himem {
   4.103 +first		dd	?		;   0  u32 first;
   4.104 +cacheidx	dw	?		;   4  int cacheidx;
   4.105 +pageidx		dw	?		;   6  int pageidx;
   4.106 +cache		dd	1024 dup(?)	;   8  int cache;
   4.107 +page		dd	1024 dup(?)	;4104  int page;
   4.108 +ends					;}; // size=8200
   4.109 +	endif
   4.110 +
   4.111  ;***************************************************************
   4.112  ;u32* malloc_bufv_or_die(struct image_himem *m);
   4.113  ;***************************************************************
   4.114 @@ -456,6 +463,16 @@
   4.115  		push	bx
   4.116  		push	si
   4.117  		xchg	ax,si
   4.118 +	ifdef	LARGE_IMAGES
   4.119 +		mov	cx,[word ((image_himem si).size) + 2]
   4.120 +		shr	cx,4			; pages index size = size >> 20
   4.121 +		add	cx,8+4096+8
   4.122 +		call	malloc_or_die
   4.123 +		mov	ecx,4096+4095		; cnt = 1+(m->size+PAGE_MASK)/PAGE_SIZE;
   4.124 +		add	ecx,[(image_himem si).size]
   4.125 +		shr	ecx,12
   4.126 +		mov	[curdata],ax
   4.127 +	else
   4.128  		mov	ecx,[(image_himem si).size]
   4.129  		dec	ecx
   4.130  		shr	ecx,12
   4.131 @@ -466,59 +483,88 @@
   4.132  ; our malloc zeroes allocated mem: bufv[cnt]=0;
   4.133  ; Allocate pages, storing addrs in addrbuf
   4.134  		call	malloc_or_die
   4.135 -                pop	cx
   4.136 -		push	cx			; _sort:nel
   4.137 -		push	ax			; _sort:base
   4.138 +		pop	cx
   4.139 +		push	ax
   4.140 +	endif
   4.141  		mov	[(image_himem si).bufv],ax
   4.142 -		xchg	ax,bx
   4.143 +		xchg	ax,si
   4.144  @@vcpi_alloc:
   4.145                  xor     edx,edx
   4.146                  mov     ax,0DE04h
   4.147                  int     67h
   4.148  		or	ah,ah
   4.149 -		jz	@@ok
   4.150  		mov	bx,offset vcpi_alloc_err
   4.151 -		jmp	die
   4.152 -@@ok:
   4.153 -		mov	[bx],edx
   4.154 -		add	bx,4
   4.155 +		jnz	die
   4.156 +; for (i = cnt-1; i >= 0; i--)
   4.157 +	ifdef	LARGE_IMAGES
   4.158 +		mov	eax,ecx
   4.159 +		dec	eax
   4.160 +	else
   4.161 +		mov	ax,cx
   4.162 +		dec	ax
   4.163 +		cwde
   4.164 +	endif
   4.165 +		shl	eax,12		; i*_4k
   4.166 +; if (edx < pm.fallback+i*_4k && edx >= pm.fallback) again
   4.167 +		extrn	_pm
   4.168 +		mov	bx,offset _pm+2
   4.169 +		push	eax
   4.170 +		add	eax,[bx-2+2]
   4.171 +		cmp	eax,edx		; pm.fallback+i*_4k <= edx ?
   4.172 +		pop	eax		; i*_4k
   4.173 +		jbe	@@pmok
   4.174 +		cmp	edx,[bx-2+2]	; edx >= pm.fallback ?
   4.175 +		jae	@@vcpi_alloc
   4.176 +@@pmok:
   4.177 +; if (edx >= initrd.fallback+i*_4k && edx < initrd.fallback+initrd.size) again
   4.178 +		extrn	_initrd
   4.179 +		mov	bx,offset _initrd+2
   4.180 +		add	eax,[bx-2+2]	; +initrd.fallback
   4.181 +		cmp	eax,edx		; initrd.fallback+i*_4k > edx ?
   4.182 +		ja	@@initrdok
   4.183 +		mov	eax,[bx-2+6]	; initrd.size
   4.184 +		add	eax,[bx-2+2]	; +initrd.fallback
   4.185 +		cmp	eax,edx		; initrd.fallback+initrd.size > edx ?
   4.186 +@@jnc_vcpi_alloc:
   4.187 +		ja	@@vcpi_alloc
   4.188 +@@initrdok:
   4.189 +	ifdef	LARGE_IMAGES
   4.190 +		cmp	[(data_himem si).first],0
   4.191 +		jne	@@notfirst
   4.192 +		mov	[(data_himem si).first],edx
   4.193 +@@notfirst:
   4.194 +		mov	bx,[(data_himem si).cacheidx]
   4.195 +		cmp	bh,4
   4.196 +		jae	@@nextpage
   4.197 +		shl	bx,2
   4.198 +		inc	[(data_himem si).cacheidx]
   4.199 +		mov	[(data_himem bx+si).cache],edx
   4.200 +		loopd	@@vcpi_alloc
   4.201 +		mov	[(data_himem bx+si).cache],ecx	; last is 0
   4.202 +@@nextpage:
   4.203 +		and	[(data_himem si).cacheidx],0
   4.204 +		mov	bx,[(data_himem si).pageidx]
   4.205 +		mov	[(data_himem bx+si).page],edx
   4.206 +		add	[(data_himem si).pageidx],4
   4.207 +		push	cx
   4.208 +		lea	cx,[(data_himem si).cache]
   4.209 +		ifdef	NO386
   4.210 +		push	edx
   4.211 +		pop	dx
   4.212 +		pop	ax
   4.213 +		endif
   4.214 +		call	storepage		; storepage(edx,cx)	
   4.215 +		pop	cx
   4.216 +		or	ecx,ecx			; clear C
   4.217 +		jnz	@@jnc_vcpi_alloc
   4.218 +		mov	[dword (data_himem si).cacheidx],ecx
   4.219 +		xchg	ax,si
   4.220 +	else
   4.221 +		mov	[si],edx
   4.222 +		lodsd				; si=+4
   4.223  		loop	@@vcpi_alloc
   4.224 -@@again:
   4.225 -		call	_sort
   4.226 -		extrn	_initrd
   4.227 -		cmp	si,offset _initrd
   4.228 -		jne	@@quit
   4.229  		pop	ax
   4.230 -		pop	cx
   4.231 -		push	cx			; _sort:nel
   4.232 -		push	ax			; _sort:base = m->bufv
   4.233 -;again:
   4.234 -; for (i = cnt-1; i >= 0; i--) {
   4.235 -@@chkloop:
   4.236 -		mov	bx,cx
   4.237 -		dec	bx
   4.238 -;   if  (m->bufv[i] > m->fallback+i*_4k && m->bufv[i] < m->fallback+m->size) {
   4.239 -		shl	bx,2
   4.240 -		add	bx,ax			; m->bufv
   4.241 -		mov	edx,[bx]		; m->bufv[i]
   4.242 -		sub	edx,[(image_himem si).fallback]
   4.243 -		cmp	edx,[(image_himem si).size]
   4.244 -		jae	@@chknext
   4.245 -		shr	edx,12
   4.246 -		cmp	dx,cx
   4.247 -		jb	@@chknext
   4.248 -;     m->bufv[i] = vcpi_alloc_or_die();
   4.249 -;     sort(m->bufv,cnt);
   4.250 -;     goto again;
   4.251 -		mov	cx,1
   4.252 -		jmp	@@vcpi_alloc
   4.253 -;   }
   4.254 -; }
   4.255 -@@chknext:
   4.256 -		loop	@@chkloop
   4.257 -@@quit:
   4.258 -		pop	ax
   4.259 -		pop	cx
   4.260 +	endif
   4.261  		pop	si
   4.262  		ret
   4.263  
   4.264 @@ -526,16 +572,189 @@
   4.265  
   4.266  
   4.267  ;***************************************************************
   4.268 -;void next_chunk(struct image_himem *m);
   4.269 +; void memcpy_image(struct image_himem *m);
   4.270  ;***************************************************************
   4.271 -        proc    _next_chunk near
   4.272 +        global  _memcpy_image:near
   4.273 +        proc    _memcpy_image near
   4.274  
   4.275 +		pop	ax			;caller return address
   4.276  		pop	bx
   4.277 +		push	bx
   4.278 +		push	ax
   4.279 +		ifndef	NO386
   4.280 +		mov	edx,[(image_himem bx).fallback]
   4.281 +		mov	eax,[(image_himem bx).buf]
   4.282 +		cmp	eax,edx			; if (m->fallback != m->buf)
   4.283 +		jz	@@skip			;   memcpy32(m->fallback,0,m->buf,m->size)
   4.284 +	ifdef	LARGE_IMAGES
   4.285 +		mov	ecx,[(image_himem bx).size]
   4.286 +memcpy_imagez:
   4.287 +		push	ecx
   4.288 +	else
   4.289 +		push	[(image_himem bx).size]
   4.290 +	endif
   4.291 +		push	eax
   4.292 +		push	0
   4.293 +call_memcpy32:
   4.294 +		push	edx
   4.295 +		else
   4.296 +		mov	ax,[word ((image_himem bx).fallback)]
   4.297 +		mov	dx,[word ((image_himem bx).fallback)+2]
   4.298 +		mov	cx,[word ((image_himem bx).buf)]
   4.299 +		cmp	ax,cx			; if (m->fallback != m->buf)
   4.300 +		jnz	@@do
   4.301 +		cmp	dx,[word ((image_himem bx).buf)+2]
   4.302 +		jz	@@skip			;   memcpy32(m->fallback,0,m->buf,m->size)
   4.303 +@@do:
   4.304 +		push	[word ((image_himem bx).size)+2]
   4.305 +		push	[word ((image_himem bx).size)]
   4.306 +		push	[word ((image_himem bx).buf)+2]
   4.307 +		push	cx
   4.308 +		xor	cx,cx
   4.309 +		push	cx
   4.310 +call_memcpy32:
   4.311 +		push	dx
   4.312 +		push	ax
   4.313 +	ifdef	LARGE_IMAGES
   4.314 +		jmp	@@memcpy
   4.315 +memcpy_imagez:
   4.316 +		push	ecx
   4.317 +		push	eax
   4.318 +		push	0
   4.319 +		push	edx
   4.320 +	endif
   4.321 +		endif
   4.322 +@@memcpy:
   4.323 +		extrn	_memcpy32:near
   4.324 +		call	near _memcpy32
   4.325 +		add	sp,14
   4.326 +@@skip:
   4.327 +		ret
   4.328 +
   4.329 +        endp    _memcpy_image
   4.330 +
   4.331 +;***************************************************************
   4.332 +;void storepage(u32 *dst, u16 src);
   4.333 +;***************************************************************
   4.334 +        global  _storepage:near
   4.335 +        proc    _storepage near
   4.336 +
   4.337 +		pop	ax			;caller return address
   4.338 +		pop	bx
   4.339 +		pop	cx
   4.340 +		push	cx
   4.341 +		push	bx
   4.342 +		push	ax
   4.343 +		ifndef	NO386
   4.344 +		mov	edx,[bx]
   4.345 +		else
   4.346 +		mov	ax,[bx]
   4.347 +		mov	dx,[bx+2]
   4.348 +		endif
   4.349 +storepage:
   4.350 +		ifndef	NO386
   4.351 +		push	0
   4.352 +		push	4096
   4.353 +		push	0
   4.354 +		else
   4.355 +		xor	bx,bx
   4.356 +		push	bx
   4.357 +		mov	bh,4096/256
   4.358 +		push	bx
   4.359 +		xor	bx,bx
   4.360 +		push	bx
   4.361 +		endif
   4.362 +		push	cx
   4.363 +		push	ds
   4.364 +		jmp	call_memcpy32
   4.365 +
   4.366 +        endp    _storepage
   4.367 +
   4.368 +
   4.369 +	ifdef	LARGE_IMAGES
   4.370 +;***************************************************************
   4.371 +;void reset_bufv(u32 *p);
   4.372 +;***************************************************************
   4.373 +        global  _reset_bufv:near
   4.374 +        proc    _reset_bufv near
   4.375 +
   4.376 +		pop	bx			;caller return address
   4.377  		pop	ax
   4.378  		push	ax
   4.379  		push	bx
   4.380 -		push	si di
   4.381 -		xchg	ax,di
   4.382 +		mov	[curdata],ax
   4.383 +		xchg	ax,bx
   4.384 +		and	[dword (data_himem bx).cacheidx],0
   4.385 +		ret
   4.386 +
   4.387 +        endp    _reset_bufv
   4.388 +
   4.389 +;***************************************************************
   4.390 +;u32* prev_bufv();
   4.391 +;u32* prev_bufv();
   4.392 +;***************************************************************
   4.393 +        global  _prev_bufv:near
   4.394 +        global  _next_bufv:near
   4.395 +        proc    _prev_bufv near
   4.396 +
   4.397 +		stc
   4.398 +		db	73h			; jnc
   4.399 +_next_bufv:
   4.400 +		clc
   4.401 +		sbb	ax,ax
   4.402 +		stc
   4.403 +		rcl	ax,1			; -1/+1
   4.404 +		xor	ecx,ecx
   4.405 +		push	si
   4.406 +		mov	si,[curdata]
   4.407 +		add	ax,[(data_himem si).cacheidx]
   4.408 +		test	ax,0fc00h
   4.409 +		jz	@@gotpage
   4.410 +		push	ax			; FFFF / 0400
   4.411 +		sar	ax,8			; FFFC / 0004
   4.412 +		and	al,0fch
   4.413 +		add	[(data_himem si).pageidx],ax
   4.414 +		mov	bx,[(data_himem si).pageidx]
   4.415 +		lea	bx,[(data_himem bx+si).page]
   4.416 +		mov	edx,ds
   4.417 +		shl	edx,4
   4.418 +		lea	cx,[(data_himem si).cache]		
   4.419 +		add	edx,ecx
   4.420 +		mov	eax,[bx]
   4.421 +		or	eax,eax
   4.422 +		jnz	@@pageok
   4.423 +		pop	ax
   4.424 +		xchg	ax,bx
   4.425 +		pop	si
   4.426 +		ret
   4.427 +@@pageok:
   4.428 +		mov	cx,4096
   4.429 +		call	memcpy_imagez		; get page
   4.430 +		pop	ax			; FFFF / 0400
   4.431 +		cbw
   4.432 +		shr	ax,6			; 03FF / 0000
   4.433 +@@gotpage:
   4.434 +		mov	[(data_himem si).cacheidx],ax
   4.435 +		shl	ax,2
   4.436 +		xchg	ax,bx
   4.437 +		lea	ax,[(data_himem bx+si).cache]		
   4.438 +		or	bx,[(data_himem si).pageidx]	; !pageidx && !cacheidx
   4.439 +		jnz	@@notfirst2
   4.440 +		xchg	ax,si				; &first
   4.441 +@@notfirst2:
   4.442 +		pop	si
   4.443 +		ret
   4.444 +
   4.445 +        endp    _prev_bufv
   4.446 +	endif
   4.447 +
   4.448 +
   4.449 +;***************************************************************
   4.450 +;void next_chunk(struct image_himem *m);
   4.451 +;***************************************************************
   4.452 +        proc    next_chunk near
   4.453 +
   4.454 +		push	si
   4.455  		mov	bx,[(image_himem di).fd]
   4.456  		call	close
   4.457  		ifndef	NO386
   4.458 @@ -567,44 +786,35 @@
   4.459  		jc	@@die
   4.460  		mov	[(image_himem di).fd],ax
   4.461  		mov	[(image_himem di).fd2close],ax
   4.462 -		mov	dx,2			; SEEK_END
   4.463  		xchg	ax,bx
   4.464 -		ifndef	NO386
   4.465 -		xor	ecx,ecx
   4.466 -		else
   4.467 -		xor	ax,ax
   4.468 -		xor	cx,cx
   4.469 -		endif
   4.470 -		call	lseek
   4.471 +		mov	ax,4202h		; SEEK_END
   4.472 +		call	lseek0
   4.473  @@die:
   4.474  		mov	bx,[(image_himem di).errmsg]
   4.475  		jc	die
   4.476  		mov	bx,[(image_himem di).fd]
   4.477  		ifndef	NO386
   4.478  		push	eax
   4.479 -		xor	ecx,ecx
   4.480 -		xor	dx,dx
   4.481 -		call	lseek			; rewind
   4.482 +		stc
   4.483 +		call	rewind
   4.484  		pop	eax
   4.485  @@end:
   4.486  		mov	[(image_himem di).chunk_size],eax
   4.487  		else
   4.488  		push	ax
   4.489  		push	dx
   4.490 -		xor	ax,ax
   4.491 -		xor	cx,cx
   4.492 -		cwd
   4.493 -		call	lseek			; rewind
   4.494 +		stc
   4.495 +		call	rewind
   4.496  		pop	dx
   4.497  		pop	ax
   4.498  @@end:
   4.499  		mov	[word (image_himem di).chunk_size],ax
   4.500  		mov	[word ((image_himem di).chunk_size)+2],dx
   4.501  		endif
   4.502 -		pop	di si
   4.503 +		pop	si
   4.504  		ret
   4.505  
   4.506 -        endp    _next_chunk
   4.507 +        endp    next_chunk
   4.508  
   4.509  
   4.510  ;***************************************************************
   4.511 @@ -633,7 +843,7 @@
   4.512  		mov	[word (image_himem di).size],ax	; m->size = 0L
   4.513  		mov	[word ((image_himem di).size)+2],ax
   4.514  		endif
   4.515 -		mov	[(image_himem di).next_chunk],offset _next_chunk
   4.516 +		mov	[(image_himem di).next_chunk],offset next_chunk
   4.517                  mov	si,[fname]
   4.518                  mov	[(image_himem di).state],si
   4.519  @@next:
   4.520 @@ -979,130 +1189,6 @@
   4.521          endp    _strtol
   4.522  
   4.523  
   4.524 -;***************************************************************
   4.525 -;>void sort(unsigned long  *base:BX!, size_t nel:CX)
   4.526 -;NO386 safe: only used by VCPI
   4.527 -;***************************************************************
   4.528 -        global  _sort:near
   4.529 -        proc    _sort near
   4.530 -
   4.531 -		pop	ax			;caller return address
   4.532 -                pop	bx			; base
   4.533 -		pop	cx			; nel
   4.534 -		push	cx
   4.535 -		push	bx
   4.536 -		push	ax
   4.537 -        global  sort:near
   4.538 -sort:
   4.539 -	ifndef	fastsort
   4.540 -;  bubble sort
   4.541 -		push	si
   4.542 -		shl	cx,2
   4.543 -@@loop:
   4.544 -		xor	ax,ax
   4.545 -		mov	si,4
   4.546 -		cmp	cx,si
   4.547 -		jbe	popsiret
   4.548 -@@next:
   4.549 -		mov	edx,[bx+si-4]
   4.550 -		cmp	edx,[bx+si]
   4.551 -		jbe	@@ok
   4.552 -		xchg	edx,[bx+si]
   4.553 -		mov	[bx+si-4],edx
   4.554 -		mov	ax,si
   4.555 -@@ok:
   4.556 -		add	si,4
   4.557 -		cmp	si,cx
   4.558 -		jb	@@next
   4.559 -		xchg	ax,cx
   4.560 -		jmp	@@loop
   4.561 -	else
   4.562 -;  shell sort (c) uclibc GPL
   4.563 -		push	si di
   4.564 -; {
   4.565 -;>	size_t wgap:SI;
   4.566 -;
   4.567 -;	if (nel > 1) {
   4.568 -		cmp	cx,1
   4.569 -		jbe	@@end
   4.570 -;		wgap = 0;
   4.571 -		xor	ax,ax
   4.572 -;		do {
   4.573 -@@wgaplp:
   4.574 -		mov	si,ax
   4.575 -;			wgap = 3 * wgap + 1;
   4.576 -		mov	dx,3
   4.577 -		mul	dx
   4.578 -		inc	ax
   4.579 -;		} while (wgap < (nel-1)/3);
   4.580 -		cmp	ax,cx
   4.581 -		jb	@@wgaplp
   4.582 -;		/* From the above, we know that either wgap == 1 < nel or */
   4.583 -;		/* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap <  nel. */
   4.584 -;		wgap *= 4;			/* So this can not overflow if wnel doesn't. */
   4.585 -		shl	si,2
   4.586 -;		nel *= 4;			/* Convert nel to 'wnel' */
   4.587 -		shl	cx,2
   4.588 -;		do {
   4.589 -@@lp1:
   4.590 -;>	                size_t i:DI;
   4.591 -;			i = wgap;
   4.592 -		mov	di,si
   4.593 -;			do {
   4.594 -@@lp2:
   4.595 -;>	                	size_t j:DX;
   4.596 -;				j = i;
   4.597 -		mov	dx,di
   4.598 -;				do {
   4.599 -@@lp3:
   4.600 -;>					register char *a:BX!;
   4.601 -;
   4.602 -;					j -= wgap;
   4.603 -		sub	dx,si
   4.604 -;					a = j + ((char *)base);
   4.605 -		push	bx
   4.606 -		add	bx,dx
   4.607 -;					if (cmp(a, a + wgap) <= 0) {
   4.608 -		mov	eax,[bx]
   4.609 -		cmp	eax,[bx+si]
   4.610 -		jbe	@@brk3
   4.611 -;						break;
   4.612 -;					}
   4.613 -		xchg	eax,[bx+si]
   4.614 -		mov	[bx],eax
   4.615 -;					swap(a, a + wgap);
   4.616 -		pop	bx
   4.617 -;				} while (j >= wgap);
   4.618 -		cmp	dx,si
   4.619 -		jae	@@lp3
   4.620 -		push	bx
   4.621 -@@brk3:
   4.622 -		pop	bx
   4.623 -;				i += 4;
   4.624 -		add	di,4
   4.625 -;			} while (i < nel);
   4.626 -		cmp	di,cx
   4.627 -		jb	@@lp2
   4.628 -;			wgap = (wgap - 4)/3;
   4.629 -		sub	si,4
   4.630 -		xchg	ax,si
   4.631 -		cwd
   4.632 -		mov	si,3
   4.633 -		div	si	; kill dx
   4.634 -		xchg	ax,si
   4.635 -;		} while (wgap);
   4.636 -		or	si,si
   4.637 -		jnz	@@lp1
   4.638 -@@end:
   4.639 -;	}
   4.640 -;}
   4.641 -		pop	di si
   4.642 -		ret
   4.643 -endif
   4.644 -
   4.645 -        endp    _sort
   4.646 -
   4.647 -
   4.648  		ifdef	NO386
   4.649  ;***************************************************************
   4.650  ;u16 topseg();
   4.651 @@ -1123,42 +1209,6 @@
   4.652          endp    _topseg
   4.653  		endif
   4.654  
   4.655 -;***************************************************************
   4.656 -;void rmcpy(void* rmbuf, u16 rmsize);
   4.657 -;***************************************************************
   4.658 -        global  _rmcpy:near
   4.659 -        proc    _rmcpy near
   4.660 -
   4.661 -		pop	bx			;caller return address
   4.662 -                pop	ax			; rmbuf
   4.663 -		pop	cx			; rmsize
   4.664 -		push	cx
   4.665 -		push	ax
   4.666 -		push	bx
   4.667 -		push	si di es
   4.668 -		xchg	ax,si
   4.669 -		xor	di,di
   4.670 -		ifdef	NO386
   4.671 -		call	_topseg
   4.672 -		mov	es,ax
   4.673 -		else
   4.674 -		push	9000h
   4.675 -		pop	es
   4.676 -		endif
   4.677 -		cld
   4.678 -		rep
   4.679 -		  movsb
   4.680 -		extrn	_cmdline:word
   4.681 -		mov	si,[_cmdline]
   4.682 -		mov	di,8000h
   4.683 -		mov	ch,10h			; 4k
   4.684 -		rep
   4.685 -		  movsb
   4.686 -		pop	es di si
   4.687 -		ret
   4.688 -
   4.689 -        endp    _rmcpy
   4.690 -
   4.691          ends    _TEXT
   4.692  
   4.693          end
     5.1 --- a/linld/stuff/src/CRTL.H	Thu Dec 22 20:43:12 2016 +0100
     5.2 +++ b/linld/stuff/src/CRTL.H	Thu Dec 22 21:06:17 2016 +0100
     5.3 @@ -20,10 +20,6 @@
     5.4  const O_RDONLY = 0;     // for open()
     5.5  const O_BINARY = 0;
     5.6  
     5.7 -const SEEK_SET = 0;     // for lseek()
     5.8 -const SEEK_CUR = 1;
     5.9 -const SEEK_END = 2;
    5.10 -
    5.11  extern char text_start; extern char text_end;
    5.12  extern char data_start; extern char data_end;
    5.13  extern char bss_start;  extern char bss_end;
    5.14 @@ -44,7 +40,7 @@
    5.15  extern "C" void abort();
    5.16  extern "C" int read(int fd, void* data, int sz);
    5.17  extern "C" int write(int fd, const void* data, int sz);
    5.18 -extern "C" long lseek(int fd, long sz, int dir);
    5.19 +extern "C" long lseekset(int fd, long sz);
    5.20  extern "C" void* malloc(unsigned sz);
    5.21  extern "C" void puts(const char* s);
    5.22  extern "C" void putsz(const char* s);
     6.1 --- a/linld/stuff/src/CRTLX.ASM	Thu Dec 22 20:43:12 2016 +0100
     6.2 +++ b/linld/stuff/src/CRTLX.ASM	Thu Dec 22 21:06:17 2016 +0100
     6.3 @@ -141,12 +141,11 @@
     6.4  		mov	ah,30h
     6.5  		int	21h
     6.6  		cmp	al,3
     6.7 -		mov	ax,0
     6.8  		jb	@@skip
     6.9 +		xor	di,di
    6.10  		mov	es,[cs:2Ch]
    6.11  		mov	cx,-1
    6.12 -		xor	di,di
    6.13 -		xor	al,al
    6.14 +		mov	ax,di
    6.15  @@loop1:
    6.16  		repne
    6.17  		  scasb
    6.18 @@ -349,6 +348,38 @@
    6.19  		
    6.20          endp    _try_default_args
    6.21  
    6.22 +struc		isostate	; struct isostate {
    6.23 +fd		dw	?	; 0	int fd;
    6.24 +fileofs		dd	?	; 2	unsigned long fileofs;
    6.25 +filesize	dd	?	; 6	unsigned long filesize;
    6.26 +filemod		dw	?	;10	unsigned short filemod;
    6.27 +filename	dw	?	;12	char *filename;
    6.28 +dirofs		dd	?	;14	unsigned long dirofs;
    6.29 +dirsize		dd	?	;16	unsigned long dirsize;
    6.30 +curdirofs	dd	?	;20	unsigned long curdirofs;
    6.31 +curdirsize	dd	?	;24	unsigned long curdirsize;
    6.32 +curpos		dd	?	;28	unsigned long curpos;
    6.33 +ends				; } isostate;
    6.34 +;***************************************************************
    6.35 +;unsigned long isolseek(unsigned long offset);
    6.36 +;***************************************************************
    6.37 +        global  _isolseek:near
    6.38 +        proc    _isolseek near
    6.39 +
    6.40 +		pop	ax
    6.41 +		pop	dx
    6.42 +		pop	cx
    6.43 +		push	cx
    6.44 +		push	dx
    6.45 +		push	ax
    6.46 +		xor	ax,ax
    6.47 +		extrn	_isostate:isostate
    6.48 +		mov	bx,[_isostate.fd]
    6.49 +		extrn	lseekset:near
    6.50 +		jmp	near lseekset		; (bx=fd, sz=cx:dx)
    6.51 +		
    6.52 +        endp    _isolseek
    6.53 +
    6.54          ends    _TEXT
    6.55  
    6.56          end
     7.1 --- a/linld/stuff/src/HIMEM.CPP	Thu Dec 22 20:43:12 2016 +0100
     7.2 +++ b/linld/stuff/src/HIMEM.CPP	Thu Dec 22 21:06:17 2016 +0100
     7.3 @@ -6,6 +6,81 @@
     7.4  #include "crtl.h"
     7.5  #include "common.h"
     7.6  
     7.7 +struct image_himem pm;
     7.8 +struct image_himem initrd;
     7.9 +
    7.10 +// Called from inside kernel just before rm->pm
    7.11 +// _loadds _saveregs: done by hand
    7.12 +void far last_ditch() {
    7.13 +    cli();  // we start doing *really* destructive things to DOS/BIOS
    7.14 +            // it means: do not even try to enable ints
    7.15 +            // or call BIOS services after this
    7.16 +    asm {
    7.17 +        push    ds
    7.18 +        push    cs
    7.19 +        pop     ds
    7.20 +#ifndef NO386
    7.21 +        pusha
    7.22 +#else
    7.23 +        push	ax
    7.24 +        push	bx
    7.25 +        push	cx
    7.26 +        push	dx
    7.27 +#endif
    7.28 +    }
    7.29 +    struct image_himem *m = &pm;
    7.30 +    if(((u16 *)&m->fallback)[1] >= 0x10) m->fallback = _1m; // >= _1m ?
    7.31 +    if(vcpi==0) {
    7.32 +        // Move kernel
    7.33 +        memcpy_image(m);
    7.34 +        // Move initrd
    7.35 +        memcpy_image(&initrd);
    7.36 +    } else { //vcpi
    7.37 +        vm2rm();
    7.38 +        // Move kernel
    7.39 +        // 'Gathering' copy in chunks of PAGE_SIZE
    7.40 +        // No risk of overlapping: kernel is copied from above to 1m mark
    7.41 +        m->size = initrd.size = PAGE_SIZE;
    7.42 +        u32 *p = m->bufv;
    7.43 +	reset_bufv(p);
    7.44 +	if (p) do {
    7.45 +            m->buf = *p;
    7.46 +            memcpy_image(m);
    7.47 +            next(p); m->fallback+=PAGE_SIZE;
    7.48 +        } while(*p);
    7.49 +        // Move initrd
    7.50 +	m = &initrd;
    7.51 +        if(m->fallback) {
    7.52 +            // This is tricky: copy initrd backwards to reduce
    7.53 +            // risk of overlapping: use the fact that initrd is copied
    7.54 +            // to the very top of ram
    7.55 +            // (overlapping still can happen with more than 256mb ram)
    7.56 +            // (generic solution for this overwrite problem, anyone?)
    7.57 +            p=m->bufv;
    7.58 +	    reset_bufv(p);
    7.59 +            do {
    7.60 +                next(p); m->fallback+=PAGE_SIZE;
    7.61 +            } while(*p);
    7.62 +            do {
    7.63 +                prev(p); m->fallback-=PAGE_SIZE;
    7.64 +                m->buf = *p;
    7.65 +                memcpy_image(m);
    7.66 +            } while(p != m->bufv);
    7.67 +        }
    7.68 +    }
    7.69 +    asm {
    7.70 +#ifndef NO386
    7.71 +        popa
    7.72 +#else
    7.73 +        pop	dx
    7.74 +        pop	cx
    7.75 +        pop	bx
    7.76 +        pop	ax
    7.77 +#endif
    7.78 +        pop     ds
    7.79 +    }
    7.80 +}
    7.81 +
    7.82  int skip_xmmalloc;
    7.83  void load_image(struct image_himem *m) {
    7.84      no_exit++;       // die() won't return to DOS
    7.85 @@ -13,7 +88,7 @@
    7.86      m->buf = m->fallback;
    7.87      u32 buf;
    7.88      u32* bufv= &buf;
    7.89 -    if(m->fallback >= _1m) {
    7.90 +    if(((u16 *)&m->fallback)[1] >= 0x10) { // >= _1m ?
    7.91  	if(vcpi) {
    7.92  	    bufv = malloc_bufv_or_die(m);	// update m->bufv
    7.93  	}
    7.94 @@ -24,13 +99,12 @@
    7.95      buf = m->buf;
    7.96      do {
    7.97  	u8 xfer_buf[PAGE_SIZE];
    7.98 -        u16 size = read_image(m, xfer_buf, PAGE_SIZE);
    7.99 -        if(s16(size) <= 0) break;
   7.100 -        memcpy32(*bufv, seg(xfer_buf), ofs(xfer_buf), PAGE_SIZE);
   7.101 -	if (bufv != &buf) bufv++;
   7.102 +        u16 size;
   7.103 +	if(s16(size = read_image(m, xfer_buf, PAGE_SIZE)) <= 0) break;
   7.104 +        storepage(bufv, ofs(xfer_buf));
   7.105 +	if (bufv != &buf) next(bufv);
   7.106          buf += size;
   7.107      } while (*bufv);
   7.108      if(m->remaining) die("Read error");
   7.109      close(m->fd2close);
   7.110  }
   7.111 -
     8.1 --- a/linld/stuff/src/ISO9660.CPP	Thu Dec 22 20:43:12 2016 +0100
     8.2 +++ b/linld/stuff/src/ISO9660.CPP	Thu Dec 22 21:06:17 2016 +0100
     8.3 @@ -3,123 +3,120 @@
     8.4  #include "iso9660.h"
     8.5  #define __ROCKRIDGE
     8.6  
     8.7 -char *isofilename;
     8.8 -unsigned long isofileofs, isofilesize;
     8.9 -unsigned short isofilemod;
    8.10 -int isofd;
    8.11 -
    8.12  #define SECTORSZ 2048
    8.13  #define SECTORBITS 11
    8.14  static char buffer[SECTORSZ];
    8.15 +struct isostate isostate;
    8.16  
    8.17  static int readsector(unsigned long offset)
    8.18  {
    8.19 -	return (lseek(isofd, offset, SEEK_SET) != -1
    8.20 -		    && read(isofd, buffer, SECTORSZ) == SECTORSZ);
    8.21 +	return (isolseek(offset) != -1
    8.22 +		    && read(isostate.fd, buffer, SECTORSZ) == SECTORSZ);
    8.23  }
    8.24  
    8.25  int isoread(char *data, unsigned size)
    8.26  {
    8.27  	int get, n;
    8.28  	
    8.29 -	if (size > isofilesize)
    8.30 -		size = isofilesize;
    8.31 -	if (lseek(isofd, isofileofs, SEEK_SET) == -1)
    8.32 +	struct isostate *x=&isostate;
    8.33 +	if (size > x->filesize)
    8.34 +		size = x->filesize;
    8.35 +	if (isolseek(x->fileofs) == -1)
    8.36  		return -1;
    8.37  	for (get = size; get; get -= n, data += n) {
    8.38 -		n = read(isofd,data,get);
    8.39 +		n = read(x->fd,data,get);
    8.40  		if (n < 0)
    8.41  			return n;
    8.42  		if (n == 0)
    8.43  			break;
    8.44 -		isofileofs += n;
    8.45 -		isofilesize -= n;
    8.46 +		x->fileofs += n;
    8.47 +		x->filesize -= n;
    8.48  	}
    8.49  	return size - get;
    8.50  }
    8.51  
    8.52 -static unsigned long isodirofs, isodirsize;
    8.53  int isoreset(char *name)
    8.54  {
    8.55 +	struct isostate *x=&isostate;
    8.56  	if (name)
    8.57 -		//isofd = open(name, O_RDONLY);
    8.58 -		isofd = open(name);
    8.59 +		//x->fd = open(name, O_RDONLY);
    8.60 +		x->fd = open(name);
    8.61  	if (!readsector(16UL * 2048) || strhead(buffer+1,"CD001")) {
    8.62 -		//close(isofd);
    8.63 +		//close(x->fd);
    8.64  		return -1;
    8.65  	}
    8.66 -	isodirofs = * (unsigned long *) (buffer + 0x9E);
    8.67 -	isodirofs <<= SECTORBITS;
    8.68 -	isodirsize = * (unsigned long *) (buffer + 0xA6);
    8.69 +	x->dirofs = * (unsigned long *) (buffer + 0x9E);
    8.70 +	x->dirofs <<= SECTORBITS;
    8.71 +	x->dirsize = * (unsigned long *) (buffer + 0xA6);
    8.72  	return 0;
    8.73  }
    8.74  
    8.75  int isoreaddir(int restart)
    8.76  {
    8.77 -	static unsigned long pos, dirofs, dirsize;
    8.78  	static char dots[] = "..";
    8.79  	int size, n;
    8.80  #ifdef __ROCKRIDGE
    8.81  	char *endname;
    8.82  #endif
    8.83 +	struct isostate *x=&isostate;
    8.84  
    8.85  	if (restart) {
    8.86 -		dirofs = isodirofs;
    8.87 -		dirsize = isodirsize;
    8.88 -		pos = SECTORSZ;
    8.89 +		x->curdirofs = x->dirofs;
    8.90 +		x->curdirsize = x->dirsize;
    8.91 +		x->curpos = SECTORSZ;
    8.92  	}
    8.93 -	if (pos >= SECTORSZ || * (short *) (buffer + pos) == 0) {
    8.94 -		if (dirsize < SECTORSZ) return -1;
    8.95 -		readsector(dirofs);
    8.96 -		dirofs += SECTORSZ;
    8.97 -		dirsize -= SECTORSZ;
    8.98 -		pos = 0;
    8.99 +	if (x->curpos >= SECTORSZ || * (short *) (buffer + x->curpos) == 0) {
   8.100 +		if (x->curdirsize < SECTORSZ) return -1;
   8.101 +		readsector(x->curdirofs);
   8.102 +		x->curdirofs += SECTORSZ;
   8.103 +		x->curdirsize -= SECTORSZ;
   8.104 +		x->curpos = 0;
   8.105  	}
   8.106 -	size = * (short *) (buffer + pos);
   8.107 +	size = * (short *) (buffer + x->curpos);
   8.108  	if (size == 0)
   8.109  		return -1;
   8.110 -	isofileofs = (* (unsigned long *) (buffer + pos + 2)) << SECTORBITS;
   8.111 -	isofilesize = * (unsigned long *) (buffer + pos + 10);
   8.112 -	isofilemod = (buffer[pos + 25] & 2) ? 0040755 : 0100755;
   8.113 +	x->fileofs = (* (unsigned long *) (buffer + x->curpos + 2)) << SECTORBITS;
   8.114 +	x->filesize = * (unsigned long *) (buffer + x->curpos + 10);
   8.115 +	x->filemod = (buffer[x->curpos + 25] & 2) ? 0040755 : 0100755;
   8.116  #ifdef __ROCKRIDGE
   8.117  	endname = NULL;
   8.118 -	n = (buffer[pos + 32] + pos + 34) & -2;
   8.119 +	n = (buffer[x->curpos + 32] + x->curpos + 34) & -2;
   8.120  	do {
   8.121  		int len = buffer[n + 2];
   8.122  		switch (* (short *) (buffer + n)) {
   8.123  		case 0x4D4E: // NM
   8.124 -			isofilename = buffer + n + 5;
   8.125 +			x->filename = buffer + n + 5;
   8.126  			endname = buffer + n + len;
   8.127  			break;
   8.128  		case 0x5850: // PX
   8.129 -			isofilemod = * (short *) (buffer + n + 4);
   8.130 +			x->filemod = * (short *) (buffer + n + 4);
   8.131  			break;
   8.132  		}
   8.133  		n += len;
   8.134  	}
   8.135 -	while (n + 2 < pos + size);
   8.136 +	while (n + 2 < x->curpos + size);
   8.137  	if (endname)
   8.138  		*endname = 0;
   8.139  	else
   8.140  #endif
   8.141  	{
   8.142 -		isofilename = buffer + pos + 33;
   8.143 -		switch (* (short *) (isofilename - 1)) {
   8.144 +		x->filename = buffer + x->curpos + 33;
   8.145 +		switch (* (short *) (x->filename - 1)) {
   8.146  		case 0x0101:
   8.147 -			isofilename = dots;
   8.148 +			x->filename = dots;
   8.149  			break;
   8.150  		case 0x0001:
   8.151 -			isofilename = dots + 1;
   8.152 +			x->filename = dots + 1;
   8.153  			break;
   8.154  		default:
   8.155 -			n = isofilename[-1];
   8.156 -			if (* (short *) (isofilename + n - 2) == 0x313B)
   8.157 +			n = x->filename[-1];
   8.158 +			if (* (short *) (x->filename + n - 2) == 0x313B)
   8.159  				n -= 2; // remove ;1
   8.160 -			if (isofilename[n - 1] == '.') n--;
   8.161 -			isofilename[n] = 0;
   8.162 +			if (x->filename[n - 1] == '.') n--;
   8.163 +			x->filename[n] = 0;
   8.164  		}
   8.165  	}
   8.166 -	pos += size;
   8.167 +	x->curpos += size;
   8.168  	return 0;
   8.169  }
   8.170  
   8.171 @@ -129,6 +126,7 @@
   8.172  	int restart;
   8.173  	char *name, *s, c;
   8.174  	int _64bits = cpuhaslm();
   8.175 +	struct isostate *x=&isostate;
   8.176  
   8.177  retry32:
   8.178  	name = filename;
   8.179 @@ -142,24 +140,24 @@
   8.180  		c = *s;
   8.181  		*s = 0;
   8.182  		for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
   8.183 -			char *n = name, *i = isofilename;
   8.184 +			char *n = name, *i = x->filename;
   8.185  			if (_64bits) {
   8.186  				int len = strlen(name);
   8.187 -				if (strhead(isofilename, name)) continue;
   8.188 +				if (strhead(x->filename, name)) continue;
   8.189  				n = "64";
   8.190  				i += len;
   8.191  			}
   8.192  			if (strcmp(n, i)) continue;
   8.193 -			if (IS_DIR(isofilemod)) {
   8.194 -				isodirofs = isofileofs;
   8.195 -				isodirsize = isofilesize;
   8.196 +			if (IS_DIR(x->filemod)) {
   8.197 +				x->dirofs = x->fileofs;
   8.198 +				x->dirsize = x->filesize;
   8.199  				if (c) {
   8.200  					*s++ = c;
   8.201  					name = s;
   8.202  					goto next;
   8.203  				}
   8.204  			}
   8.205 -			lseek(isofd, isofileofs, SEEK_SET);
   8.206 +			isolseek(x->fileofs);
   8.207  			return 0;
   8.208  		}
   8.209  		if (_64bits) {
     9.1 --- a/linld/stuff/src/ISO9660.H	Thu Dec 22 20:43:12 2016 +0100
     9.2 +++ b/linld/stuff/src/ISO9660.H	Thu Dec 22 21:06:17 2016 +0100
     9.3 @@ -1,9 +1,21 @@
     9.4  #ifndef __ISO9660_H
     9.5  #define __ISO9660_H
     9.6 -extern char *isofilename;
     9.7 -extern unsigned long isofileofs, isofilesize;
     9.8 -extern unsigned short isofilemod;
     9.9 -extern int isofd;
    9.10 +extern struct isostate {
    9.11 +	int fd;
    9.12 +	unsigned long fileofs;
    9.13 +	unsigned long filesize;
    9.14 +	unsigned short filemod;
    9.15 +	char *filename;
    9.16 +//private
    9.17 +	unsigned long dirofs, dirsize;
    9.18 +	unsigned long curdirofs, curdirsize, curpos;
    9.19 +} isostate;
    9.20 +#define isofd isostate.fd
    9.21 +#define	isofileofs isostate.fileofs
    9.22 +#define	isofilesize isostate.filesize
    9.23 +#define	isofilemod isostate.filemod
    9.24 +#define	isofilename isostate.filename
    9.25 +extern "C" int unsigned long isolseek(unsigned long offset);
    9.26  extern int isoreset(char *name);
    9.27  extern int isoopen(char *name);
    9.28  extern int isoreaddir(int restart);
    10.1 --- a/linld/stuff/src/JUMP.ASM	Thu Dec 22 20:43:12 2016 +0100
    10.2 +++ b/linld/stuff/src/JUMP.ASM	Thu Dec 22 21:06:17 2016 +0100
    10.3 @@ -21,7 +21,7 @@
    10.4          segment _TEXT byte public use16 'CODE'
    10.5  
    10.6  ;***************************************************************
    10.7 -;void set_sregs_jump_seg_ofs(u32 csip, u32 sssp);
    10.8 +;void set_sregs_jump_seg_ofs(u32 csip);
    10.9  ;****** Never returns
   10.10  ;***************************************************************
   10.11          global  _set_sregs_jump_seg_ofs:near
   10.12 @@ -30,15 +30,43 @@
   10.13  		extrn	dos_shutdown:near
   10.14  
   10.15  		pop	ax			;caller return address
   10.16 -		test	[byte _pm_high],-1	; load high ? clear CF
   10.17 +		ifdef	NO386
   10.18 +		extrn	_topseg:near
   10.19 +		call	near _topseg
   10.20 +		mov	es,ax
   10.21 +		else
   10.22 +		push	9000h
   10.23 +		pop	es
   10.24 +		endif
   10.25 +		pop	cx			; ip
   10.26 +		pop	dx			; cs
   10.27 +		push	es
   10.28 +		pop	ss
   10.29 +		mov	sp,0A000h
   10.30 +		push	dx cx
   10.31 +		extrn	_rm_buf:word
   10.32 +		mov	si,[_rm_buf]
   10.33 +		xor	di,di
   10.34 +		extrn	_rm_size:word
   10.35 +		mov	cx,[_rm_size]
   10.36 +		;cld
   10.37 +		rep
   10.38 +		  movsb
   10.39 +		extrn	_cmdline:word
   10.40 +		mov	si,[_cmdline]
   10.41 +		mov	di,8000h
   10.42 +		mov	ch,10h			; 4k
   10.43 +		rep
   10.44 +		  movsb
   10.45 +		cmp	[_pm_high],cl		; load high ?
   10.46  		jne	isbzimage
   10.47  		; finish loading
   10.48  		extrn   @last_ditch$qv:near
   10.49  		push	cs
   10.50  		call	@last_ditch$qv
   10.51 -		mov	bx,[word _pm+2+2]	; get pm->fallback high word
   10.52 +		mov	ax,[word _pm+2+2]	; get pm->fallback high word
   10.53  		; self move
   10.54 -		cld
   10.55 +		;cld
   10.56  		push	9900h			; 4096 bytes for cmdline
   10.57  	;push	9820h			; 512 bytes for cmdline
   10.58  		pop	es			; min 2048 bytes for stack
   10.59 @@ -51,18 +79,11 @@
   10.60  		  movsb
   10.61  		push	es
   10.62  		call	near doretf		; mov cs,es
   10.63 -		stc
   10.64 -isbzimage:
   10.65 -		pop	cx			; ip
   10.66 -		pop	dx			; cs
   10.67 -		pop	ax			; sp
   10.68 -		pop	ss			; ss
   10.69 -		xchg	sp,ax
   10.70 -		push	dx cx
   10.71 -		jnc	nomove
   10.72 +		push	ss
   10.73 +		pop	es
   10.74  		push	cs
   10.75  		pop	ds
   10.76 -		push	bx
   10.77 +		push	ax
   10.78  		call	near dos_shutdown
   10.79  		;in	al,70h
   10.80  		;or	al,80h			; disable NMI
   10.81 @@ -112,11 +133,11 @@
   10.82  notelks:
   10.83  		endif
   10.84  
   10.85 -nomove:
   10.86 +isbzimage:
   10.87  		push	ss
   10.88  		pop	ds
   10.89 -		push	ss
   10.90 -		pop	es
   10.91 +		;push	ss
   10.92 +		;pop	es
   10.93  		push	ss
   10.94  		pop	fs
   10.95  		push	ss
    11.1 --- a/linld/stuff/src/LINLD.CPP	Thu Dec 22 20:43:12 2016 +0100
    11.2 +++ b/linld/stuff/src/LINLD.CPP	Thu Dec 22 21:06:17 2016 +0100
    11.3 @@ -36,18 +36,18 @@
    11.4  
    11.5  static char _cmdline[256];
    11.6  int main(int argc, char *argv[]) {
    11.7 +
    11.8 +    (void) argc;
    11.9 +
   11.10      // Believe it or not - this enables A20
   11.11      // on my box! Must be DOS in HMA...   -vda
   11.12      puts("LINLD v" VERSION_STR "+");
   11.13  
   11.14 -    if(argc<2) {
   11.15 -dosyntax:
   11.16 -        syntax();
   11.17 -    }
   11.18 -
   11.19      // Parse command line
   11.20 -    {for (char i=0;;) {
   11.21 -	char *s=*++argv;
   11.22 +    if (argv[1]) {for (char i=0;;) {
   11.23 +	char *s;
   11.24 +	argv++;
   11.25 +	s=*argv;
   11.26  	i++;
   11.27  	if (!s) {
   11.28  	    puts(load_kernel());
   11.29 @@ -113,9 +113,10 @@
   11.30  	    cmdline = (const char *) _cmdline;
   11.31          }
   11.32  	else
   11.33 -	    goto dosyntax;
   11.34 +	    break;
   11.35      }}
   11.36 +    syntax();
   11.37  
   11.38      // Let compiler be happy
   11.39 -    // return _AX;
   11.40 +    return _AX;
   11.41  }
    12.1 --- a/linld/stuff/src/LOAD.CPP	Thu Dec 22 20:43:12 2016 +0100
    12.2 +++ b/linld/stuff/src/LOAD.CPP	Thu Dec 22 21:06:17 2016 +0100
    12.3 @@ -44,7 +44,6 @@
    12.4  */
    12.5  
    12.6  struct kernelparams_t {
    12.7 -    u8      pad0;
    12.8      u8      setup_sects;    // 01F1 The size of the setup in sectors
    12.9                              //      boot sector is NOT included here
   12.10      u16     ro_flag;        // 01F2 If set, the root is mounted readonly
   12.11 @@ -101,7 +100,7 @@
   12.12      u8      pad20[0x01e0-0xa0];
   12.13                              // this is set by rm setup:
   12.14      u32     alt_mem_size;   // 01E0 extended memory size in Kb (from int 0x15 fn 0xe801)
   12.15 -    u8      pad28[0x01f0-0x1e4];
   12.16 +    u8      pad28[0x01f1-0x1e4];
   12.17      struct kernelparams_t params;
   12.18  }; //__attribute((packed));
   12.19  
   12.20 @@ -112,95 +111,15 @@
   12.21  const u32 HdrS = 'H' + ('d'<<8) + (u32('r')<<16) + (u32('S')<<24);
   12.22  
   12.23  u8* rm_buf;
   12.24 -static u16 rm_size;
   12.25 +u16 rm_size;
   12.26  u8 pm_high;
   12.27 -struct image_himem pm;
   12.28 -struct image_himem initrd;
   12.29 -
   12.30 -static void memcpy_image(struct image_himem *m) {
   12.31 -    if (m->fallback != m->buf)
   12.32 -        memcpy32(
   12.33 -            m->fallback,    // dst seg,ofs
   12.34 -            0, m->buf,      // src seg,ofs
   12.35 -            m->size         // size
   12.36 -        );
   12.37 -}
   12.38 -
   12.39 -// Called from inside kernel just before rm->pm
   12.40 -// _loadds _saveregs: done by hand
   12.41 -void far last_ditch() {
   12.42 -    cli();  // we start doing *really* destructive things to DOS/BIOS
   12.43 -            // it means: do not even try to enable ints
   12.44 -            // or call BIOS services after this
   12.45 -    asm {
   12.46 -        push    ds
   12.47 -        push    cs
   12.48 -        pop     ds
   12.49 -#ifndef NO386
   12.50 -        pusha
   12.51 -#else
   12.52 -        push	ax
   12.53 -        push	bx
   12.54 -        push	cx
   12.55 -        push	dx
   12.56 -#endif
   12.57 -    }
   12.58 -    if(pm.fallback > _1m) pm.fallback = _1m;
   12.59 -    if(vcpi==0) {
   12.60 -        // Move kernel
   12.61 -        memcpy_image(&pm);
   12.62 -        // Move initrd
   12.63 -        memcpy_image(&initrd);
   12.64 -    } else { //vcpi
   12.65 -        vm2rm();
   12.66 -        // Move kernel
   12.67 -        // 'Gathering' copy in chunks of PAGE_SIZE
   12.68 -        // No risk of overlapping: kernel is copied from above to 1m mark
   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 -            memcpy_image(&pm);
   12.74 -            p++; pm.fallback+=PAGE_SIZE;
   12.75 -        }
   12.76 -        // Move initrd
   12.77 -        if(initrd.fallback) {
   12.78 -            // This is tricky: copy initrd backwards to reduce
   12.79 -            // risk of overlapping: use the fact that initrd is copied
   12.80 -            // to the very top of ram
   12.81 -            // (overlapping still can happen with more than 256mb ram)
   12.82 -            // (generic solution for this overwrite problem, anyone?)
   12.83 -            p=initrd.bufv;
   12.84 -            do {
   12.85 -                p++; initrd.fallback+=PAGE_SIZE;
   12.86 -            } while(*p);
   12.87 -            do {
   12.88 -                p--; initrd.fallback-=PAGE_SIZE;
   12.89 -                initrd.buf = *p;
   12.90 -                memcpy_image(&initrd);
   12.91 -            } while(p != initrd.bufv);
   12.92 -        }
   12.93 -    }
   12.94 -    asm {
   12.95 -#ifndef NO386
   12.96 -        popa
   12.97 -#else
   12.98 -        pop	dx
   12.99 -        pop	cx
  12.100 -        pop	bx
  12.101 -        pop	ax
  12.102 -#endif
  12.103 -        pop     ds
  12.104 -    }
  12.105 -}
  12.106 +extern struct image_himem pm, initrd;
  12.107  
  12.108  // register value to launch the kernel real mode code
  12.109  #ifdef NO386
  12.110 -static u32 sssp;
  12.111  static u32 csip;
  12.112  extern "C" u16 topseg();
  12.113  #else
  12.114 -const  u32 sssp=0x9000A000;
  12.115  static u32 csip=0x90200000;
  12.116  #define topseg() 0x9000
  12.117  #endif
  12.118 @@ -209,7 +128,6 @@
  12.119  char* load_kernel() {
  12.120  
  12.121  #ifdef NO386
  12.122 -    sssp=((u32)topseg()<<16)+0xA000;
  12.123      csip=((u32)(topseg()+0x20)<<16);
  12.124  #endif
  12.125      // Open kernel, read first kb, check it
  12.126 @@ -231,10 +149,10 @@
  12.127          die(kernel_file_error);
  12.128      }
  12.129  
  12.130 -    if(!kernelparams->setup_sects) {
  12.131 +    if(kernelparams->setup_sects == 0) {
  12.132  #if 1
  12.133          if(* (int *) &first1k->pad10[0x3F-0x24] == 0x3AE8) {
  12.134 -            lseek(pm.fd,rm_seek=0x200,SEEK_SET);
  12.135 +            lseekset(pm.fd,rm_seek=0x200);
  12.136              csip=((u32)topseg()<<16)+0x0042;
  12.137          }
  12.138          else
  12.139 @@ -275,7 +193,8 @@
  12.140              hook_int15_88();
  12.141  
  12.142              // * will be called just before rm -> pm
  12.143 -            kernelparams->realmode_switch_ofs = ofs(last_ditch);
  12.144 +	    extern void far last_ditch();
  12.145 +            kernelparams->realmode_switch_ofs = ofs((void *)last_ditch);
  12.146              kernelparams->realmode_switch_seg = seg(last_ditch);
  12.147          }
  12.148          if(kernelparams->kernel_version)
  12.149 @@ -307,14 +226,17 @@
  12.150      // Try to load kernel high, maybe even blindly storing it
  12.151      // in unallocated memory as a last resort
  12.152  
  12.153 -    pm.fallback = (u32((u16(_CS)+0x1FFF)&0xF000)<<4);
  12.154 -    pm.size -= rm_size;
  12.155 -    pm.chunk_size -= rm_size;
  12.156 -    if(pm.fallback+pm.size > (((u32)topseg())<<4) || pm_high) {
  12.157 -        pm.fallback = _1m+_64k;
  12.158 +  {
  12.159 +    struct image_himem *m = &pm;
  12.160 +    m->fallback = (u32((u16(_CS)+0x1FFF)&0xF000)<<4);
  12.161 +    m->size -= rm_size;
  12.162 +    m->chunk_size -= rm_size;
  12.163 +    if(m->fallback+m->size > (((u32)topseg())<<4) || pm_high) {
  12.164 +        m->fallback = _1m+_64k;
  12.165      }
  12.166  
  12.167 -    load_image(&pm);
  12.168 +    load_image(m);
  12.169 +  }
  12.170      return version_string;
  12.171  }
  12.172  
  12.173 @@ -322,7 +244,7 @@
  12.174  
  12.175  void load_initrd() {
  12.176      struct image_himem *m = &initrd;
  12.177 -    if (!initrd_name && !initrd.fd) return;
  12.178 +    if (!initrd_name && !m->fd) return;
  12.179      m->errmsg = "Can't use initrd file";
  12.180      if (!pm.errmsg) {
  12.181  noinitrd:
  12.182 @@ -338,7 +260,7 @@
  12.183      }
  12.184  
  12.185      load_image(m);
  12.186 -    struct kernelparams_t *kernelparams = (kernelparams_t *)(rm_buf+0x1F0);
  12.187 +    struct kernelparams_t *kernelparams = &(((first1k_t*) rm_buf)->params);
  12.188      if(kernelparams->header == HdrS) {
  12.189          kernelparams->initrd_buf  = m->fallback;
  12.190          kernelparams->initrd_size = m->size;
  12.191 @@ -352,17 +274,13 @@
  12.192          u16 new_SP=u16(heap_top)+0x100;
  12.193          if(_SP>new_SP) _SP=new_SP;
  12.194      }
  12.195 -    if( u16(_CS)+(u16(_SP)>>4) >= topseg() ) {
  12.196 +    if( (u16(_SP)>>4)+u16(_CS) >= topseg() ) {
  12.197          // Oops! We can stomp on our toes... better stop now
  12.198          die("Loaded too close to 9000:0");
  12.199      }
  12.200  
  12.201      cli(); // we start doing destructive things to DOS
  12.202  
  12.203 -    // Move rm loader & commandline to 0x90000
  12.204 -    // overkill: copy PAGE_SIZE bytes
  12.205 -    rmcpy(rm_buf, rm_size);
  12.206 -
  12.207 -    // Jump to kernel rm code
  12.208 -    set_sregs_jump_seg_ofs(csip, sssp);
  12.209 +    // Move rm loader & commandline to 0x90000, Jump to kernel rm code
  12.210 +    set_sregs_jump_seg_ofs(csip);
  12.211  }
    13.1 --- a/linld/stuff/src/MEMCPY32.ASM	Thu Dec 22 20:43:12 2016 +0100
    13.2 +++ b/linld/stuff/src/MEMCPY32.ASM	Thu Dec 22 21:06:17 2016 +0100
    13.3 @@ -116,34 +116,34 @@
    13.4  		push	bp
    13.5  		mov	bp,sp
    13.6  		sub	sp,TEMP_SIZE
    13.7 +		;cld
    13.8                  pushf
    13.9 -		cld
   13.10                  push    ds es
   13.11  
   13.12  			ifndef	NO386
   13.13  
   13.14                  pushad
   13.15 +		mov	cl,4
   13.16                  movzx   esi,[srcseg]
   13.17 -                shl     esi,4
   13.18 -                add     [srcofs],esi
   13.19 -                mov     esi,[srcofs]
   13.20 +                shl     esi,cl
   13.21 +                add     esi,[srcofs]
   13.22 +                mov     [srcofs],esi		; for memcpy_vcpi
   13.23                  mov     edi,[dstofs]
   13.24  
   13.25  	ifndef	pm_only
   13.26  		mov	eax,esi
   13.27 -		or	eax,edi
   13.28 -		shr	eax,20			; >1mb ?
   13.29 -                jnz     pmcopy
   13.30 -		mov	eax,esi
   13.31 -		shr	eax,4
   13.32 +		shr	eax,cl
   13.33  		mov	edx,edi
   13.34 -		shr	edx,4
   13.35 +		shr	edx,cl
   13.36 +		mov	ecx,esi
   13.37 +		or	ecx,edi
   13.38 +		shr	ecx,20			; >1mb ?
   13.39 +                jnz     @@pmcopy
   13.40  @@movlp:
   13.41  		mov	ds,ax
   13.42  		mov	es,dx
   13.43  		inc	ax
   13.44  		inc	dx
   13.45 -		xor	ecx,ecx
   13.46  		mov	cl,0Fh
   13.47  		and	si,cx
   13.48  		and	di,cx
   13.49 @@ -151,19 +151,19 @@
   13.50                  sub     [sz],ecx
   13.51              rep movsb
   13.52                  ja	@@movlp
   13.53 -		jmp	done
   13.54 +		jmp	@@done
   13.55  	endif
   13.56 -pmcopy:
   13.57 +@@pmcopy:
   13.58  			else
   13.59  
   13.60  		push	si
   13.61  		xor	bx,bx
   13.62  		xor	dx,dx
   13.63  		xor	si,si
   13.64 -		mov	ax,[bp+si+8]		; srcseg
   13.65 +		mov	ax,[bp+8]		; srcseg
   13.66  		call	near N_LXLSH@4
   13.67 -		add	[bp+si+10],ax		; srcofs lo
   13.68 -		adc	[bp+si+10+2],dx		; srcofs hi
   13.69 +		add	[bp+10],ax		; srcofs lo
   13.70 +		adc	[bp+10+2],dx		; srcofs hi
   13.71  @@2flat:
   13.72  		mov	ax,[bp+si+10]		; srcofs, dstofs lo
   13.73  		mov	dx,[bp+si+10+2]		; srcofs, dstofs hi
   13.74 @@ -174,8 +174,8 @@
   13.75  		jnz	@@2flat
   13.76  		pop	dx			; dstseg
   13.77  		pop	ax			; srcseg
   13.78 -		or	bx,bx			; <1mb ?
   13.79 -                jnz     pmcopy
   13.80 +		test	bx,bx			; <1mb ? (clear C)
   13.81 +                jnz     @@pmcopy
   13.82  		push	di
   13.83  @@movlp:
   13.84  		mov	ds,ax
   13.85 @@ -190,13 +190,13 @@
   13.86  		inc	cx
   13.87                  sub     [word sz],cx
   13.88              rep movsb
   13.89 -		jae	@@movlp
   13.90 +		ja	@@movlp
   13.91  		dec	[word sz+2]
   13.92 -                jns	@@movlp			; mov 1-16 more bytes...
   13.93 -		pop	di si
   13.94 -		jmp	done16
   13.95 -pmcopy:
   13.96 +		jns	@@movlp			; mov 1-16 more bytes...
   13.97 +		pop	di
   13.98 +@@pmcopy:
   13.99  		pop	si
  13.100 +		js	@@done16
  13.101                  pushad
  13.102                  mov     esi,[srcofs]
  13.103                  mov     edi,[dstofs]
  13.104 @@ -204,7 +204,7 @@
  13.105  			endif
  13.106  
  13.107                  mov     ecx,[sz]
  13.108 -                jecxz   done
  13.109 +                jecxz   @@done
  13.110  
  13.111  		smsw	ax
  13.112  		test	al,1
  13.113 @@ -216,11 +216,8 @@
  13.114  		extrn	call_pm_routine:near
  13.115                  call    near call_pm_routine ; Call pm copy routine via vcpi pm
  13.116                  pop     ax
  13.117 -		jmp	done
  13.118 +		jmp	@@done
  13.119  @@real_mode:
  13.120 -		mov	dx,-1
  13.121 -
  13.122 -with_movsw:
  13.123                  cmp     esi,edi
  13.124                  jae     @@do_copy
  13.125                  add     esi,ecx         ;src<dst: we must do
  13.126 @@ -236,13 +233,13 @@
  13.127                  mov     eax,cs
  13.128                  shl     eax,4
  13.129                  addzx_e ax,<offset GDT>
  13.130 -                mov     [word GDTR],dx          ;GDT limit = 0FFFFh
  13.131 +                mov     [word GDTR],-1          ;GDT limit = 0FFFFh
  13.132                  mov     [dword GDTR+2],eax      ;GDT base
  13.133                  lgdt    [GDTR]
  13.134  
  13.135  ;****** Go into pm *********************************************
  13.136                  mov     eax,cr0
  13.137 -                or      al,01h          ;CR0_PE on
  13.138 +                inc     ax		;CR0_PE on
  13.139                  mov     cr0,eax
  13.140                  jmp     short $+2       ;*Required*!
  13.141                                          ;3+ NOPs also work fine (chkd on 386)
  13.142 @@ -254,6 +251,7 @@
  13.143                  db      66h     ;operand width override for ecx
  13.144                  db      67h     ;address width override for esi/edi
  13.145              rep movsb
  13.146 +		cld
  13.147  
  13.148  ;****** Return to rm *******************************************
  13.149                  dec     ax              ;CR0_PE off
  13.150 @@ -263,9 +261,9 @@
  13.151  
  13.152  ;****** Return *************************************************
  13.153                  lgdt    [oldGDTR]
  13.154 -done:
  13.155 +@@done:
  13.156                  popad
  13.157 -done16:
  13.158 +@@done16:
  13.159                  pop     es ds
  13.160                  popf
  13.161  		mov	sp,bp
    14.1 --- a/linld/stuff/src/MEMTOP.ASM	Thu Dec 22 20:43:12 2016 +0100
    14.2 +++ b/linld/stuff/src/MEMTOP.ASM	Thu Dec 22 21:06:17 2016 +0100
    14.3 @@ -38,7 +38,7 @@
    14.4  ;***************************************************************
    14.5  ;        proc    _memtop_e801 near
    14.6  
    14.7 -                push    cx bx
    14.8 +                ;push    cx bx
    14.9                  xor     cx,cx           ;fix to work around buggy
   14.10                  xor     dx,dx           ;  BIOSes which dont clear/set
   14.11                  stc                     ;  carry on pass/error of
   14.12 @@ -54,7 +54,7 @@
   14.13  @@use_cxdx:     xchg    ax,cx
   14.14  @@end_kludge:                   ;now: dx=64k units above 16m
   14.15                                  ;     ax=1k units above 1m below 16m (max 3c00h)
   14.16 -                pop     bx cx
   14.17 +                ;pop     bx cx
   14.18                  test    dx,dx
   14.19                  jz      tokb            ;dx=0 here, ax=kbs above 1m
   14.20                  xor     ax,ax           ;ignore info on low 16M (assume full)
   14.21 @@ -169,17 +169,22 @@
   14.22  
   14.23  		ifndef  xmm_hook
   14.24                  mov     ax,4300h
   14.25 +		ifdef	NO386
   14.26 +		cwd
   14.27 +		endif
   14.28                  int     2fh
   14.29 -                cmp     al,80h
   14.30 +                cmp     al,80h			; 80h = XMS driver installed
   14.31                  je      @@skip
   14.32  		endif
   14.33 +		ifndef	NO386
   14.34  		push	0
   14.35  		pop	es
   14.36  		mov	bx,15*4
   14.37 -		ifndef	NO386
   14.38  		mov	eax,[bx]
   14.39  		mov	[saved15],eax
   14.40  		else
   14.41 +		mov	es,dx
   14.42 +		mov	bx,15*4
   14.43  		mov	ax,[bx]
   14.44  		mov	[word saved15],ax
   14.45  		mov	ax,[bx+2]
    15.1 --- a/linld/stuff/src/TAZBOOT.CPP	Thu Dec 22 20:43:12 2016 +0100
    15.2 +++ b/linld/stuff/src/TAZBOOT.CPP	Thu Dec 22 21:06:17 2016 +0100
    15.3 @@ -18,7 +18,7 @@
    15.4  {
    15.5  	m->chunk_size = 0;
    15.6  	if (m->state >= initrd_state.cnt) return;
    15.7 -	lseek(m->fd,initrd_state.ofs[m->state],SEEK_SET);
    15.8 +	lseekset(m->fd,initrd_state.ofs[m->state]);
    15.9  	m->chunk_size = initrd_state.size[m->state];
   15.10  	m->state++;
   15.11  }
   15.12 @@ -63,9 +63,10 @@
   15.13  static void bootiso(char **iso)
   15.14  {
   15.15  	char *init = " rdinit=/init.exe", *mode="menu";
   15.16 -	char *s, c, rootfs[16], fallback[16];
   15.17 +	char c, rootfs[16], fallback[16];
   15.18  	int restart, isknoppix = 0;
   15.19  	unsigned long magic;
   15.20 +	struct isostate *x=&isostate;
   15.21  	
   15.22  	if (!*iso || isoreset(*iso) < 0) return;
   15.23  	skip_xmmalloc++;
   15.24 @@ -85,12 +86,12 @@
   15.25  	} while (isoopen("isolinux") >= 0);		// Knoppix
   15.26  	fallback[0] = 0;
   15.27  	for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
   15.28 -		if (strstr(isofilename, ".gz"))
   15.29 -			strcpy(fallback, isofilename);
   15.30 -		if (strhead(isofilename, "rootfs") 
   15.31 -			|| c > isofilename[6]) continue;
   15.32 -		strcpy(rootfs, isofilename);
   15.33 -		c = isofilename[6];
   15.34 +		if (strstr(x->filename, ".gz"))
   15.35 +			strcpy(fallback, x->filename);
   15.36 +		if (strhead(x->filename, "rootfs") 
   15.37 +			|| c > x->filename[6]) continue;
   15.38 +		strcpy(rootfs, x->filename);
   15.39 +		c = x->filename[6];
   15.40  	}
   15.41  
   15.42  	strcpy(_cmdline,"rw root=/dev/null autologin bootfrom=");
   15.43 @@ -109,13 +110,13 @@
   15.44  		if (isoopen(initrd) >= 0) {
   15.45  			addinitrd();
   15.46  		}
   15.47 -		if (*init && lseek(isofd, 20L, SEEK_SET) != -1) {
   15.48 -			read(isofd, &isofileofs, 4);
   15.49 -			read(isofd, &magic, 4);
   15.50 -			isofileofs &= 0xFFFFL;
   15.51 -			isofilesize = magic & 0xFFFFL;
   15.52 -			isofileofs -= 0xC0L + isofilesize;
   15.53 -			if (isofilesize) addinitrd();
   15.54 +		if (*init && isolseek(20L) != -1) {
   15.55 +			read(x->fd, &x->fileofs, 4);
   15.56 +			read(x->fd, &magic, 4);
   15.57 +			x->fileofs &= 0xFFFFL;
   15.58 +			x->filesize = magic & 0xFFFFL;
   15.59 +			x->fileofs -= 0xC0L + x->filesize;
   15.60 +			if (x->filesize) addinitrd();
   15.61  			else init="";
   15.62  		}
   15.63  		load_initrds();
   15.64 @@ -126,12 +127,13 @@
   15.65  		strcat(_cmdline,ultoa(magic));
   15.66  	}
   15.67  	if (isknoppix) {
   15.68 +		char *s;
   15.69  		if (iso[0][1] == ':')
   15.70  			*iso += 2;
   15.71  		for (s = *iso; *s; s++)
   15.72  			if (*s == '\\') *s = '/';
   15.73  	}
   15.74 -	close(isofd);
   15.75 +	close(x->fd);
   15.76  	boot_kernel();
   15.77  }
   15.78  
    16.1 --- a/linld/stuff/src/VCPI.ASM	Thu Dec 22 20:43:12 2016 +0100
    16.2 +++ b/linld/stuff/src/VCPI.ASM	Thu Dec 22 21:06:17 2016 +0100
    16.3 @@ -240,7 +240,7 @@
    16.4  ; Check that mapping for low 640k is 1:1
    16.5                  mov     si,[page0_ofs]
    16.6                  xor     bx,bx
    16.7 -                cld
    16.8 +                ;cld
    16.9  @@map_chk:
   16.10                  lodsd
   16.11                  shr     eax,12
   16.12 @@ -373,7 +373,7 @@
   16.13  
   16.14          ; Do copying
   16.15                  mov     ecx,4096/2
   16.16 -                cld
   16.17 +                ;cld
   16.18  ;;              cmp     esi,edi
   16.19  ;;              jae     @@do_copy
   16.20  ;;              add     esi,ecx         ;src<dst: we must do
   16.21 @@ -413,6 +413,7 @@
   16.22                ;;pushad
   16.23                  push    cs      ;*
   16.24                  push    ds
   16.25 +                push    es
   16.26                  mov     [saved_ss],ss
   16.27                  mov     [saved_sp],sp
   16.28  
   16.29 @@ -429,8 +430,8 @@
   16.30                  mov     ss,ax           ;   or you may get limit violations
   16.31                  mov     ds,ax           ;   later in rm
   16.32                  mov     es,ax           ;   (actually I prefer 4gig limits :-)
   16.33 -                mov     fs,ax           ;
   16.34 -                mov     gs,ax           ;
   16.35 +                ;mov     fs,ax           ;
   16.36 +                ;mov     gs,ax           ;
   16.37  
   16.38  ; Black magic here
   16.39                  mov     eax,cr0
   16.40 @@ -442,6 +443,7 @@
   16.41  
   16.42  ; Now we are in rm, but not yet: have to restore sregs:
   16.43                  lss     sp,[saved_ss_sp]; SS
   16.44 +                pop     es              ; ES
   16.45                  pop     ds              ; DS
   16.46                 ;push    cs      ;* done earlier
   16.47                  push    offset @@next
   16.48 @@ -450,7 +452,8 @@
   16.49                ;;popad
   16.50                ;;popf
   16.51                  pop	esi
   16.52 -                ret             ; We don't care much about rest (ES/FS/GS)
   16.53 +                ret             ; We don't care much about rest (FS/GS)
   16.54 +
   16.55          endp    _vm2rm
   16.56  
   16.57          ends    _TEXT
    17.1 --- a/linld/stuff/src/_BEG.ASM	Thu Dec 22 20:43:12 2016 +0100
    17.2 +++ b/linld/stuff/src/_BEG.ASM	Thu Dec 22 21:06:17 2016 +0100
    17.3 @@ -24,6 +24,7 @@
    17.4  		mov	[byte bx],0		; clear bss + heap + sp
    17.5  		inc	bx
    17.6  		jne	clearbss
    17.7 +                cld
    17.8  
    17.9  ;***************************************************************
   17.10  ; check CPU
   17.11 @@ -38,6 +39,7 @@
   17.12  		pop	dx
   17.13  		popf
   17.14  		add	dh,bh		; NS=386+, NC=286
   17.15 +		mov	bx,offset msg_badcpu
   17.16  		ifndef	NO386
   17.17                  js	no_vcpi   	;it is a 86/186/286, not a 386+
   17.18  		else
   17.19 @@ -45,15 +47,9 @@
   17.20  		endif
   17.21  ; Check for vm
   17.22                  smsw    ax      ;SMSW cannot be trapped! :-)
   17.23 -                and     ax,1	;MSW_PE
   17.24 +                and     al,1	;MSW_PE
   17.25  ; We're in vm
   17.26 -                jnz     check_vcpi
   17.27 -
   17.28 -; It's a 386 in real mode, chk for paging (crazy but possible)
   17.29 -                mov     edx,cr0
   17.30 -                shl     edx,1   ;CR0_PG to CF
   17.31 -		jc	no_vcpi
   17.32 -		jmp	endcpu
   17.33 +		jz	check_rm_paging
   17.34  
   17.35  ;***************************************************************
   17.36  ; checks for vcpi
   17.37 @@ -75,10 +71,10 @@
   17.38                  jne     no_vcpi
   17.39  
   17.40  ; Check emm manager status and version
   17.41 -                mov     ah,40h          ; get status
   17.42 -                int     67h
   17.43 -                test    ah,ah
   17.44 -                jnz     no_vcpi
   17.45 +                ;mov     ah,40h          ; get status
   17.46 +                ;int     67h
   17.47 +                ;test    ah,ah
   17.48 +                ;jnz     no_vcpi
   17.49                  mov     ah,46h          ; get version
   17.50                  int     67h
   17.51                  test    ah,ah
   17.52 @@ -94,26 +90,29 @@
   17.53                ;;push    dx              ;$ save handle
   17.54                  mov     ax,0DE00h       ; check for vcpi present
   17.55                  int     67h
   17.56 -                mov     al,1
   17.57                  test    ah,ah
   17.58 -                jz      is386vcpi
   17.59 -              ;;pop     dx              ;$ handle
   17.60 -              ;;mov     ax,4500h        ; DEALLOCATE PAGES
   17.61 -              ;;int     67h
   17.62 -no_vcpi:
   17.63 -		mov	bx,offset msg_badcpu
   17.64 -                extrn   die:near
   17.65 -godie:
   17.66 -		jmp	near die
   17.67 +		jnz	no_vcpi
   17.68  is386vcpi:
   17.69 -		mov	[_vcpi],al
   17.70 +		inc	[_vcpi]
   17.71                  extrn   prepare_vcpi:near
   17.72  		call	prepare_vcpi
   17.73  ;    get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
   17.74                  ;extrn   _get_vcpi_interface:near
   17.75  		;call	_get_vcpi_interface
   17.76  		mov	bx,offset msg_badmapping
   17.77 -		jz	godie
   17.78 +		jnz	endcpu
   17.79 +no_vcpi:
   17.80 +              ;;pop     dx              ;$ handle
   17.81 +              ;;mov     ax,4500h        ; DEALLOCATE PAGES
   17.82 +              ;;int     67h
   17.83 +                extrn   die:near
   17.84 +godie:
   17.85 +		jmp	near die
   17.86 +check_rm_paging:
   17.87 +; It's a 386 in real mode, chk for paging (crazy but possible)
   17.88 +                mov     edx,cr0
   17.89 +                shl     edx,1   ;CR0_PG to CF
   17.90 +		jc	no_vcpi
   17.91  endcpu:
   17.92  
   17.93  ;***************************************************************
   17.94 @@ -125,7 +124,6 @@
   17.95                  ;push	ax			; envp (already cleared)
   17.96                  ;mov	[word di],ax		; argv[0] = 0 (idem)
   17.97                  mov	si,80h
   17.98 -                cld
   17.99                  lodsb
  17.100                  cmp	al,7Eh
  17.101                  jbe	alok