wok-6.x rev 19515

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents 099a4d67f199
children c832599ce658
files linld/receipt linld/stuff/src/!COMPILE.BAT linld/stuff/src/!COMPILEX.BAT linld/stuff/src/A20.ASM 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/ISO9660.CPP linld/stuff/src/ISO9660.H linld/stuff/src/JUMP.ASM linld/stuff/src/LINK.CMD linld/stuff/src/LINKX.CMD 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/XMM.ASM linld/stuff/src/_BEG.ASM
line diff
     1.1 --- a/linld/receipt	Tue Nov 22 18:08:00 2016 +0100
     1.2 +++ b/linld/receipt	Tue Nov 22 21:19:01 2016 +0100
     1.3 @@ -19,21 +19,25 @@
     1.4  {
     1.5  	mv DIST $src 2> /dev/null
     1.6  	cd $src
     1.7 -	patch -p0 < $stuff/load.u
     1.8 -	patch -p0 < $stuff/jump.u
     1.9 -	patch -p0 < $stuff/a20.u
    1.10 -	patch -p0 < $stuff/memcpy32.u
    1.11 -	sed -i 's/^@pause/rem &/;s|^tasm|& /l|' LINLD$SUFFIX/*.BAT
    1.12 +	rm LINLD$SUFFIX/CRTL.CPP
    1.13 +	cp $stuff/src/* LINLD$SUFFIX/
    1.14 +	cp -a LINLD$SUFFIX TAZBOOT
    1.15 +	sed -i 's/-3/-DNO386/' TAZBOOT/BCCOPT.OPT
    1.16  	unix2dos > MAKE.BAT <<EOT
    1.17  d:
    1.18  cd linld$SUFFIX
    1.19 -!compile.bat
    1.20 +$(cat LINLD$SUFFIX/!COMPILE.BAT)
    1.21 +cd ..
    1.22 +cd tazboot
    1.23 +$(cat TAZBOOT/!COMPILEX.BAT)
    1.24  EOT
    1.25  	SDL_VIDEODRIVER=dummy dosbox MAKE.BAT -exit -c "mount D $src"
    1.26  	cp LINLD$SUFFIX/LINLD.COM linld.com
    1.27 +	cp TAZBOOT/TAZBOOT.COM tazboot.com
    1.28  	objdump -D -b binary -mi386 -Maddr16,data16 --adjust-vma=0x100 \
    1.29  		linld.com > linld.lst
    1.30  	upx linld.com
    1.31 +	upx tazboot.com
    1.32  	cc -o tobzimage.o -Wa,-algms=tobzimage.lst -c $stuff/tobzimage.S
    1.33  	objcopy -O binary tobzimage.o tobzimage.bin
    1.34  	cp $stuff/tobzimage .
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linld/stuff/src/!COMPILE.BAT	Tue Nov 22 21:19:01 2016 +0100
     2.3 @@ -0,0 +1,16 @@
     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 +rem @pause
    2.11 +bcc @bccopt.opt -S -mt *.cpp
    2.12 +tasm /l /m load.asm
    2.13 +tasm /l /m himem.asm
    2.14 +tasm /l /m linld.asm
    2.15 +tasm /l /m iso9660.asm
    2.16 +bcc @bccopt.opt -c -mt *.cpp > cpp.log
    2.17 +rem @pause
    2.18 +tlink /m /s /t @link.cmd > lnk.log
    2.19 +rem @pause
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/linld/stuff/src/!COMPILEX.BAT	Tue Nov 22 21:19:01 2016 +0100
     3.3 @@ -0,0 +1,13 @@
     3.4 +path ..\BC31;%PATH%
     3.5 +call !clean.bat
     3.6 +tasm /l /m /dNO386 *.asm > asm.log
     3.7 +rem @pause
     3.8 +bcc @bccopt.opt -S -mt *.cpp
     3.9 +tasm /l /m load.asm
    3.10 +tasm /l /m himem.asm
    3.11 +tasm /l /m tazboot.asm
    3.12 +tasm /l /m iso9660.asm
    3.13 +bcc @bccopt.opt -c -mt *.cpp > cpp.log
    3.14 +rem @pause
    3.15 +tlink /m /s /t @linkx.cmd > lnk.log
    3.16 +rem @pause
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/linld/stuff/src/A20.ASM	Tue Nov 22 21:19:01 2016 +0100
     4.3 @@ -0,0 +1,145 @@
     4.4 +;***************************************************************
     4.5 +;****** This file is distributed under GPL
     4.6 +;***************************************************************
     4.7 +                ideal
     4.8 +                %crefref
     4.9 +                %noincl
    4.10 +                %nomacs
    4.11 +                p386
    4.12 +
    4.13 +        group   DGROUP  _TEXT,_DATA
    4.14 +        assume  cs:DGROUP,ds:DGROUP
    4.15 +
    4.16 +        segment _DATA byte public use16 'DATA'
    4.17 +
    4.18 +        global  die:near
    4.19 +enable_a20_methods:
    4.20 +		dw	_enable_a20_fast, _enable_a20_kbd, _enable_a20_xmm, die
    4.21 +msg_a20		db	"Can't enable A20",0
    4.22 +
    4.23 +        ends    _DATA
    4.24 +
    4.25 +        segment _TEXT byte public use16 'CODE'
    4.26 +
    4.27 +        global  xmm_driver:near
    4.28 +        global  _enable_a20_xmm:near
    4.29 +
    4.30 +;***************************************************************
    4.31 +;void enable_a20_kbd();
    4.32 +;***************************************************************
    4.33 +        proc    _enable_a20_kbd near
    4.34 +
    4.35 +                call    @@empty_8042
    4.36 +                mov     al,0D1h         ; command write
    4.37 +                out     64h,al
    4.38 +                call    @@empty_8042
    4.39 +                mov     al,0DFh         ; A20 on
    4.40 +                out     60h,al
    4.41 +
    4.42 +; This routine checks that the keyboard command queue is empty
    4.43 +; (after emptying the output buffers)
    4.44 +; Some machines have delusions that the keyboard buffer is always full
    4.45 +; with no keyboard attached...
    4.46 +; If there is no keyboard controller, we will usually get 0xff
    4.47 +; to all the reads.  With each IO taking a microsecond and
    4.48 +; a timeout of 100,000 iterations, this can take about half a
    4.49 +; second ("delay" == out to port 0x80). That should be ok,
    4.50 +; and should also be plenty of time for a real keyboard controller
    4.51 +; to empty.
    4.52 +
    4.53 +@@empty_8042:
    4.54 +                xor     cx,cx           ; 64K iterations
    4.55 +@@loop:
    4.56 +                call    @@delay         ; 8042 status port
    4.57 +                in      al,64h          ; output buffer?
    4.58 +                test    al,1            ;
    4.59 +                jz      @@no_output
    4.60 +                call    @@delay         ; yes: read it
    4.61 +                in      al,60h          ;
    4.62 +                jmp     @@cont          ;
    4.63 +@@no_output:
    4.64 +                test    al,2            ; is input buffer full?
    4.65 +                jz      @@break         ; no - break loop
    4.66 +@@cont:
    4.67 +                loop    @@loop
    4.68 +@@break:
    4.69 +                ret
    4.70 +
    4.71 +@@delay:        out     80h,al
    4.72 +                ret
    4.73 +
    4.74 +        endp    _enable_a20_kbd
    4.75 +
    4.76 +;***************************************************************
    4.77 +;void enable_a20_fast();
    4.78 +;***************************************************************
    4.79 +        proc    _enable_a20_fast near
    4.80 +
    4.81 +; You must preserve the other bits here. Otherwise embarrasing things
    4.82 +; like laptops powering off on boot happen. Corrected version by Kira
    4.83 +; Brown from Linux 2.2
    4.84 +                in      al,92h  ;
    4.85 +                or      al,02h  ; "fast A20" version
    4.86 +                out     92h,al  ; some chips have only this
    4.87 +                ret
    4.88 +
    4.89 +        endp    _enable_a20_fast
    4.90 +
    4.91 +;***************************************************************
    4.92 +;int check_a20();
    4.93 +;***************************************************************
    4.94 +        proc    _check_a20 near
    4.95 +
    4.96 +; From linux kernel setup.S:
    4.97 +; wait until a20 really *is* enabled; it can take a fair amount of
    4.98 +; time on certain systems; Toshiba Tecras are known to have this
    4.99 +; problem.
   4.100 +
   4.101 +                push    ds es
   4.102 +		xor	bx,bx
   4.103 +		mov	ds,bx
   4.104 +		mov	cx,0FFFFh
   4.105 +		mov	es,cx
   4.106 +a20lp:
   4.107 +		cli
   4.108 +		mov	ax,0AA55h
   4.109 +		xchg	al,[bx]
   4.110 +		xchg	ah,[es:bx+10h]
   4.111 +		xchg	al,[bx]
   4.112 +		xchg	ah,[es:bx+10h]
   4.113 +		cmp	al,55h
   4.114 +		sti
   4.115 +a20ko:
   4.116 +		loopne	a20lp
   4.117 +		xchg	ax,cx
   4.118 +                pop     es ds
   4.119 +                ret
   4.120 +
   4.121 +        endp    _check_a20
   4.122 +
   4.123 +;***************************************************************
   4.124 +;void enable_a20_or_die();
   4.125 +;***************************************************************
   4.126 +        global  _enable_a20_or_die:near
   4.127 +        proc    _enable_a20_or_die near
   4.128 +
   4.129 +		push	si
   4.130 +		mov	si,offset enable_a20_methods
   4.131 +		jmp	@@check
   4.132 +@@loop:
   4.133 +		lodsw
   4.134 +		mov	bx,offset msg_a20
   4.135 +		call	ax
   4.136 +@@check:
   4.137 +		call	_check_a20
   4.138 +		jne	@@loop
   4.139 +		pop	si
   4.140 +                ret
   4.141 +
   4.142 +        endp    _enable_a20_or_die
   4.143 +
   4.144 +        ends    _TEXT
   4.145 +
   4.146 +        end
   4.147 +
   4.148 +;###### END OF FILE ############################################
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/linld/stuff/src/COMMON.H	Tue Nov 22 21:19:01 2016 +0100
     5.3 @@ -0,0 +1,82 @@
     5.4 +// This file is distributed under GPL
     5.5 +//
     5.6 +// Common defs not belonging to CRTL
     5.7 +
     5.8 +#define NL "\r\n"
     5.9 +#define VERSION_STR "0.97"
    5.10 +
    5.11 +#if 0       // DEBUG
    5.12 + #undef  NDEBUG
    5.13 + #define DEBUG
    5.14 + #define static
    5.15 +#else       // not DEBUG
    5.16 + #define NDEBUG
    5.17 + #undef  DEBUG
    5.18 +#endif
    5.19 +
    5.20 +typedef unsigned long  u32; typedef signed long  s32;
    5.21 +typedef unsigned short u16; typedef signed short s16;
    5.22 +typedef unsigned char  u8;  typedef signed char  s8;
    5.23 +
    5.24 +const u16 _16k = 16*1024u;
    5.25 +const u16 _32k = 32*1024u;
    5.26 +const u32 _64k = 64*1024ul;
    5.27 +const u32 _1m = 1024ul*1024ul;
    5.28 +
    5.29 +const PAGE_BITS = 12;
    5.30 +const PAGE_SIZE = 1<<PAGE_BITS;
    5.31 +const PAGE_MASK = PAGE_SIZE-1;
    5.32 +
    5.33 +// WARNING!
    5.34 +// BC 3.1 bug: seg() will generate incorrect code if inlined!
    5.35 +// replaced by _dirty_ hack for now
    5.36 +// u16 seg(const void far* p) { return FP_SEG(p); }
    5.37 +inline u16 seg(const void far*) { return _DS; }
    5.38 +
    5.39 +inline u16 ofs(const void* p) { return FP_OFF(p); }
    5.40 +
    5.41 +extern struct image_himem {
    5.42 +    int fd;
    5.43 +    u32 fallback;
    5.44 +    u32 size;
    5.45 +    u32 remaining;
    5.46 +    u32 buf;
    5.47 +    u32 *bufv;
    5.48 +    const char *errmsg;
    5.49 +    u32 chunk_size;
    5.50 +    void (*next_chunk)(struct image_himem *);
    5.51 +    u16 state;
    5.52 +} pm, initrd;
    5.53 +
    5.54 +extern char vcpi;
    5.55 +extern const char* kernel_name;
    5.56 +extern const char* initrd_name;
    5.57 +extern const char* cmdline;
    5.58 +extern u16 root_dev;
    5.59 +extern u16 vid_mode;
    5.60 +// External asm helpers
    5.61 +extern "C" void memcpy32(u16,u32, u16,u32, u32);
    5.62 +extern "C" void set_sregs_jump_seg_ofs(u32 csip, u32 sssp);
    5.63 +extern "C" u32 xmm_alloc(u32 size);
    5.64 +extern u32 topmem;
    5.65 +extern "C" u32 memtopz();
    5.66 +extern "C" u32 memtop();
    5.67 +extern "C" void enable_a20_or_die();
    5.68 +extern "C" int get_vcpi_interface();
    5.69 +extern "C" char* prepare_vcpi(void *pagebuf);
    5.70 +//extern "C" int call_pm_routine(void* f);
    5.71 +extern "C" void memcpy_vcpi(u32 dstofs,u16 srcseg,u16 srcofs);
    5.72 +extern "C" void vm2rm();
    5.73 +extern "C" void hook_int15_88();
    5.74 +
    5.75 +// C++ helpers
    5.76 +#ifdef DEBUG
    5.77 +extern "C" void hang();
    5.78 +#endif
    5.79 +
    5.80 +void load_image(struct image_himem *m);
    5.81 +extern "C" void open_image(const char *name, struct image_himem *m);
    5.82 +extern "C" int read_image(struct image_himem *m, void* data, int sz);
    5.83 +char* load_kernel();
    5.84 +void load_initrd();
    5.85 +void boot_kernel();
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/linld/stuff/src/CRTL.ASM	Tue Nov 22 21:19:01 2016 +0100
     6.3 @@ -0,0 +1,922 @@
     6.4 +;***************************************************************
     6.5 +;****** This file is distributed under GPL
     6.6 +;***************************************************************
     6.7 +                ideal
     6.8 +                %crefref
     6.9 +                %noincl
    6.10 +                %nomacs
    6.11 +                p386
    6.12 +
    6.13 +        group   DGROUP  _TEXT,_DATA,_BSS
    6.14 +        assume  cs:DGROUP,ds:DGROUP
    6.15 +
    6.16 +        segment _DATA byte public use16 'DATA'
    6.17 +
    6.18 +msg_hang	db      "High mem corrupted - not exiting to DOS",0
    6.19 +        global  _vcpi_alloc_err:byte
    6.20 +_vcpi_alloc_err	db	"vcpi "
    6.21 +msg_malloc      db      "malloc() failure",0
    6.22 +msg_crlf	db	13,10,0
    6.23 +
    6.24 +        ends    _DATA
    6.25 +
    6.26 +        segment _BSS byte public use16 'BSS'
    6.27 +
    6.28 +        global  _heap_top:word
    6.29 +_heap_top	dw	?
    6.30 +        global  _no_exit:byte
    6.31 +_no_exit	db	?
    6.32 +filecnt		db	?		; in fact 0 minus file count...
    6.33 +nextfilename	dw	?
    6.34 +
    6.35 +        ends    _BSS
    6.36 +
    6.37 +        segment _TEXT byte public use16 'CODE'
    6.38 +
    6.39 +;***************************************************************
    6.40 +;void puts(const char* s):
    6.41 +;void putsz(const char* s):
    6.42 +;***************************************************************
    6.43 +        global  _puts:near
    6.44 +        proc    _puts near
    6.45 +
    6.46 +		pop	ax			;caller return address
    6.47 +                pop	bx			; s
    6.48 +                push	bx
    6.49 +                push	ax
    6.50 +        global  puts:near			; puts(bx)
    6.51 +puts:
    6.52 +		call	putsz
    6.53 +                mov	bx,offset msg_crlf
    6.54 +		jmp	putsz
    6.55 +
    6.56 +        global  _putsz:near
    6.57 +_putsz:
    6.58 +		pop	ax			;caller return address
    6.59 +                pop	bx			; s
    6.60 +                push	bx
    6.61 +                push	ax
    6.62 +        global  putsz:near			; putsz(bx)
    6.63 +putsz:
    6.64 +                push	bx
    6.65 +		call	strlen
    6.66 +		pop	dx
    6.67 +		xchg	ax,cx
    6.68 +		mov	bx,1
    6.69 +                mov	ah,40h
    6.70 +		jmp	dos
    6.71 +
    6.72 +        endp    _puts
    6.73 +
    6.74 +
    6.75 +;***************************************************************
    6.76 +;int open(const char* name, int flags);
    6.77 +;***************************************************************
    6.78 +        global  _open:near
    6.79 +        proc    _open near
    6.80 +
    6.81 +		pop	cx			;caller return address
    6.82 +                pop	bx			; name
    6.83 +                pop	ax			; flags
    6.84 +                push	ax
    6.85 +                push	bx
    6.86 +                push	cx
    6.87 +        global  open:near			; open(bx,al)
    6.88 +open:
    6.89 +                mov	dx,bx
    6.90 +                mov	ah,3dh
    6.91 +dos:
    6.92 +                int	21h
    6.93 +                jnc	doret
    6.94 +fail:
    6.95 +                sbb	ax,ax			; ax=-1 CF
    6.96 +		cwd
    6.97 +doret:
    6.98 +		ifndef	NO386
    6.99 +                push	dx
   6.100 +                push	ax
   6.101 +                pop	eax
   6.102 +		endif
   6.103 +                ret
   6.104 +
   6.105 +        endp    _open
   6.106 +
   6.107 +
   6.108 +;***************************************************************
   6.109 +;int close(int fd);
   6.110 +;***************************************************************
   6.111 +        global  _close:near
   6.112 +        proc    _close near
   6.113 +
   6.114 +		pop	ax			;caller return address
   6.115 +                pop	bx			; fd
   6.116 +                push	bx
   6.117 +                push	ax
   6.118 +        global  close:near			; close(bx)
   6.119 +close:
   6.120 +		mov	ah,3Eh
   6.121 +		or	bx,bx
   6.122 +		jnz	dos
   6.123 +		ret
   6.124 +
   6.125 +        endp    _close
   6.126 +
   6.127 +
   6.128 +;***************************************************************
   6.129 +;int read(int fd, void* data, int sz);
   6.130 +;***************************************************************
   6.131 +        global  _read:near
   6.132 +        proc    _read near
   6.133 +
   6.134 +                mov	ah,3fh
   6.135 +rwio:
   6.136 +		ifndef	NO386
   6.137 +		pop	dx			;caller return address
   6.138 +                pop	ebx			; fd & data
   6.139 +                pop	cx			; sz
   6.140 +                push	cx
   6.141 +                push	ebx
   6.142 +                push	dx
   6.143 +		else
   6.144 +		mov	bx,sp
   6.145 +		mov	cx,[bx+6]
   6.146 +		mov	dx,[bx+4]
   6.147 +		mov	bx,[bx+2]
   6.148 +		endif
   6.149 +                clc
   6.150 +                jcxz	fail
   6.151 +rwioz:
   6.152 +		ifndef	NO386
   6.153 +                push	ebx
   6.154 +                pop	bx
   6.155 +                pop	dx
   6.156 +		endif
   6.157 +		jmp	dos
   6.158 +
   6.159 +        endp    _read
   6.160 +
   6.161 +
   6.162 +;***************************************************************
   6.163 +;int write(int fd, const void* data, int sz);
   6.164 +;***************************************************************
   6.165 +        global  _write:near
   6.166 +        proc    _write near
   6.167 +
   6.168 +                mov	ah,40h
   6.169 +		jmp	rwio
   6.170 +
   6.171 +        endp    _write
   6.172 +
   6.173 +
   6.174 +;***************************************************************
   6.175 +;long lseek(int fd, long sz, int dir);
   6.176 +;long rewind(int fd);
   6.177 +;***************************************************************
   6.178 +        global  _lseek:near
   6.179 +        proc    _lseek near
   6.180 +
   6.181 +		ifndef	NO386
   6.182 +		pop	ax			;caller return address
   6.183 +                pop	bx			; fd
   6.184 +                pop	ecx			; sz
   6.185 +                pop	dx			; dir
   6.186 +                push	dx
   6.187 +                push	ecx
   6.188 +                push	bx
   6.189 +                push	ax
   6.190 +		else
   6.191 +		mov	bx,sp
   6.192 +		mov	dx,[bx+8]
   6.193 +		mov	cx,[bx+6]
   6.194 +		mov	ax,[bx+4]
   6.195 +		mov	bx,[bx+2]
   6.196 +		endif
   6.197 +lseek:
   6.198 +		xchg	ax,dx			; dir
   6.199 +                mov	ah,42h
   6.200 +		ifndef	NO386
   6.201 +                push	ecx
   6.202 +                pop	dx
   6.203 +                pop	cx
   6.204 +		endif
   6.205 +		jmp	dos
   6.206 +
   6.207 +        global  _rewind:near
   6.208 +_rewind:
   6.209 +		pop	ax			;caller return address
   6.210 +                pop	bx			; fd
   6.211 +                push	bx
   6.212 +                push	ax
   6.213 +rewind:
   6.214 +		ifndef	NO386
   6.215 +		xor	ecx,ecx
   6.216 +		xor	dx,dx
   6.217 +		else
   6.218 +		xor	ax,ax
   6.219 +		xor	cx,cx
   6.220 +		cwd
   6.221 +		endif
   6.222 +		jmp	lseek
   6.223 +
   6.224 +        endp    _lseek
   6.225 +
   6.226 +
   6.227 +;***************************************************************
   6.228 +;int strlen(const char* s);
   6.229 +;***************************************************************
   6.230 +        global  _strlen:near
   6.231 +        proc    _strlen near
   6.232 +
   6.233 +		pop	ax			;caller return address
   6.234 +                pop	bx			; s
   6.235 +                push	bx
   6.236 +                push	ax
   6.237 +        global  strlen:near			; strlen(bx)
   6.238 +strlen:
   6.239 +                mov	cx,bx
   6.240 +                jcxz	@@end
   6.241 +                dec	bx
   6.242 +@@lenlp:
   6.243 +                inc	bx
   6.244 +                cmp	[byte bx],0
   6.245 +                jne	@@lenlp
   6.246 +                sub	bx,cx
   6.247 +@@end:
   6.248 +                xchg	ax,bx
   6.249 +                ret
   6.250 +
   6.251 +        endp    _strlen
   6.252 +
   6.253 +
   6.254 +;***************************************************************
   6.255 +;int strhead(const char* a,const char* b);
   6.256 +;***************************************************************
   6.257 +        global  _strhead:near
   6.258 +        proc    _strhead near
   6.259 +
   6.260 +		pop	cx			;caller return address
   6.261 +                pop	ax			; a
   6.262 +                pop	bx			; b
   6.263 +                push	bx
   6.264 +                push	ax
   6.265 +                push	cx
   6.266 +@@loop:
   6.267 +                mov	cl,[bx]			; cl = *b++
   6.268 +                inc	bx
   6.269 +		or	cl,cl			; clear C
   6.270 +		jz	fail			; return 0
   6.271 +		xchg	ax,bx
   6.272 +                xor	cl,[bx]			; cl -= *a++
   6.273 +		and	cl,0dfh			; case insensitive
   6.274 +		stc
   6.275 +		jnz	fail			; return -1
   6.276 +                inc	bx
   6.277 +		xchg	ax,bx
   6.278 +                jmp	@@loop
   6.279 +
   6.280 +        endp    _strhead
   6.281 +
   6.282 +
   6.283 +;***************************************************************
   6.284 +;char* malloc_or_die(unsigned size);
   6.285 +;***************************************************************
   6.286 +        global  _malloc_or_die:near
   6.287 +        proc    _malloc_or_die near
   6.288 +
   6.289 +		pop	ax			;caller return address
   6.290 +                pop	cx			; size
   6.291 +                push	cx
   6.292 +                push	ax
   6.293 +        global  malloc_or_die:near		; malloc_or_die(cx)
   6.294 +malloc_or_die:
   6.295 +		call	malloc
   6.296 +		jz	_diez
   6.297 +		ret
   6.298 +
   6.299 +        endp    _malloc_or_die
   6.300 +
   6.301 +
   6.302 +;***************************************************************
   6.303 +;int die(const char* msg);
   6.304 +;int diez();
   6.305 +;int abort();
   6.306 +;***************************************************************
   6.307 +        global  _die:near
   6.308 +        proc    _die near
   6.309 +
   6.310 +		pop	ax			;caller return address
   6.311 +                pop	bx			; s
   6.312 +                push	bx
   6.313 +                push	ax
   6.314 +        global  die:near			; die(bx)
   6.315 +die:
   6.316 +		call	puts
   6.317 +        global  _diez:near
   6.318 +_diez:
   6.319 +		mov	al,[_no_exit]
   6.320 +		cmp	al,0
   6.321 +		jne	@@hang
   6.322 +		extrn	exit:near
   6.323 +		inc	ax
   6.324 +		jmp	near exit
   6.325 +@@hang:
   6.326 +		mov	bx, offset msg_hang
   6.327 +		call	puts
   6.328 +        global  _abort:near
   6.329 +_abort:
   6.330 +		cli
   6.331 +@@stop:
   6.332 +		hlt
   6.333 +		jmp	@@stop
   6.334 +
   6.335 +        endp    _die
   6.336 +
   6.337 +
   6.338 +;***************************************************************
   6.339 +;void next_chunk(struct image_himem *m);
   6.340 +;***************************************************************
   6.341 +        proc    _next_chunk near
   6.342 +
   6.343 +		pop	bx
   6.344 +		pop	ax
   6.345 +		push	ax
   6.346 +		push	bx
   6.347 +		push	di
   6.348 +		xchg	ax,di
   6.349 +		mov	bx,[di]			; m->fd
   6.350 +		call	close
   6.351 +		ifndef	NO386
   6.352 +		xor	eax,eax
   6.353 +		else
   6.354 +		xor	ax,ax
   6.355 +		endif
   6.356 +		cwd
   6.357 +		mov	[di],ax			; m->fd
   6.358 +		mov	bx,[di+28]		; m->state
   6.359 +		cmp	al,[bx]			; ""
   6.360 +		jz	@@end
   6.361 +		push	si
   6.362 +		mov	si,bx
   6.363 +@@scan:
   6.364 +		lodsb
   6.365 +		mov	cx,si
   6.366 +		cmp	al,','
   6.367 +		jz	@@eos
   6.368 +		cmp	al,0
   6.369 +		jnz	@@scan
   6.370 +		dec	cx
   6.371 +@@eos:
   6.372 +		mov	[di+28],cx		; m->state
   6.373 +		dec	si
   6.374 +		push	[word si]
   6.375 +		mov	[byte si],dl		; set temp eos
   6.376 +		xchg	ax,dx			; O_RDONLY
   6.377 +		call	open
   6.378 +		pop	[word si]		; restore string
   6.379 +		pop	si
   6.380 +		jc	@@die
   6.381 +		mov	[di],ax			; m->fd
   6.382 +		mov	dx,2			; SEEK_END
   6.383 +		xchg	ax,bx
   6.384 +		ifndef	NO386
   6.385 +		xor	ecx,ecx
   6.386 +		else
   6.387 +		xor	ax,ax
   6.388 +		xor	cx,cx
   6.389 +		endif
   6.390 +		call	lseek
   6.391 +@@die:
   6.392 +		mov	bx,[di+20]		; m->errmsg
   6.393 +		jc	die
   6.394 +		mov	bx,[di]			; m->fd
   6.395 +		ifndef	NO386
   6.396 +		push	eax
   6.397 +		call	rewind
   6.398 +		pop	eax
   6.399 +@@end:
   6.400 +		mov	[di+22],eax		; m->chunk_size
   6.401 +		else
   6.402 +		push	ax
   6.403 +		push	dx
   6.404 +		call	rewind
   6.405 +		pop	dx
   6.406 +		pop	ax
   6.407 +@@end:
   6.408 +		mov	[di+22],ax		; m->chunk_size
   6.409 +		mov	[di+24],dx
   6.410 +		endif
   6.411 +		pop	di
   6.412 +		ret
   6.413 +
   6.414 +        endp    _next_chunk
   6.415 +
   6.416 +
   6.417 +;***************************************************************
   6.418 +;void open_image(const char *name, struct image_himem *m);
   6.419 +;struct image_himem {
   6.420 +; 0    int fd;
   6.421 +; 2    u32 fallback;
   6.422 +; 6    u32 size;
   6.423 +;10    u32 remaining;
   6.424 +;14    u32 buf;
   6.425 +;18    u32 *bufv;
   6.426 +;20    char *errmsg;
   6.427 +;22    u32 chunk_size;
   6.428 +;26    void (*next_chunk)(struct image_himem *);
   6.429 +;28    u16 state;
   6.430 +;};
   6.431 +;***************************************************************
   6.432 +        global  _open_image:near
   6.433 +        proc    _open_image near
   6.434 +
   6.435 +		arg	fname	:word,	\
   6.436 +			m	:word	= PARAM_SIZE
   6.437 +
   6.438 +		push	bp
   6.439 +		mov	bp,sp
   6.440 +                push	si di
   6.441 +		ifndef	NO386
   6.442 +                xor	eax,eax			; 1st loop flag + eos
   6.443 +		else
   6.444 +                xor	ax,ax			; 1st loop flag + eos
   6.445 +		endif
   6.446 +                mov	di,[m]
   6.447 +                cmp	[di],ax			; m->fd
   6.448 +                jnz	@@alreadydone
   6.449 +		ifndef	NO386
   6.450 +		mov	[di+6],eax		; m->size = 0L
   6.451 +		else
   6.452 +		mov	[di+6],ax		; m->size = 0L
   6.453 +		mov	[di+8],ax
   6.454 +		endif
   6.455 +		mov	[word di+26],offset _next_chunk
   6.456 +                mov	si,[fname]
   6.457 +                mov	[di+28],si		; m->state
   6.458 +@@next:
   6.459 +		push	di
   6.460 +                call	[word di+26]		; m->next_chunk()
   6.461 +		pop	di
   6.462 +		ifndef	NO386
   6.463 +		add	eax,3
   6.464 +		and	al,0FCh
   6.465 +		add	[di+6],eax		; m->size += m->chunk_size
   6.466 +		or	eax,eax
   6.467 +		jnz	@@next
   6.468 +		else
   6.469 +		mov	cx,ax
   6.470 +		or	cx,dx
   6.471 +		add	ax,3
   6.472 +		adc	dx,0
   6.473 +		and	al,0FCh
   6.474 +		add	[di+6],ax		; m->size += m->chunk_size
   6.475 +		adc	[di+8],dx
   6.476 +		inc	cx
   6.477 +		loop	@@next
   6.478 +		endif
   6.479 +                mov	[di+28],si		; m->state
   6.480 +		push	di
   6.481 +                call	[word di+26]		; m->next_chunk()
   6.482 +		pop	di
   6.483 +@@alreadydone:
   6.484 +                push	ax
   6.485 +image_done:
   6.486 +                pop	ax
   6.487 +                pop	di si bp
   6.488 +		ret
   6.489 +
   6.490 +        endp    _open_image
   6.491 +
   6.492 +
   6.493 +;***************************************************************
   6.494 +;int read_image(struct image_himem *m, void* data, int sz);
   6.495 +;***************************************************************
   6.496 +        global  _read_image:near
   6.497 +        proc    _read_image near
   6.498 +
   6.499 +		arg	m	:word,	\
   6.500 +			data	:word,	\
   6.501 +			sz	:word	= PARAM_SIZE
   6.502 +
   6.503 +		push	bp
   6.504 +		mov	bp,sp
   6.505 +		push	si di
   6.506 +		ifndef	NO386
   6.507 +		push	0		; return value
   6.508 +		else
   6.509 +		xor	ax,ax
   6.510 +		push	ax
   6.511 +		endif
   6.512 +		mov	di,[m]
   6.513 +@@loop:
   6.514 +		mov	ax,[word sz]
   6.515 +		mov	cx,[di+22]	; m->chunk_size
   6.516 +		cmp	ax,cx
   6.517 +		jb	@@szok
   6.518 +		cmp	[word di+24],0	; hi m->chunk_size
   6.519 +		jne	@@szok
   6.520 +		xchg	ax,cx
   6.521 +@@szok:
   6.522 +		push	ax
   6.523 +		push	[word data]
   6.524 +		push	[word di]
   6.525 +		call	_read
   6.526 +		pop	cx
   6.527 +		pop	bx
   6.528 +		add	bx,ax
   6.529 +		pop	cx
   6.530 +		xor	cx,cx
   6.531 +		sub	[di+22],ax
   6.532 +		sbb	[di+24],cx
   6.533 +@@fill:
   6.534 +		test	al,3
   6.535 +		je	@@filled
   6.536 +		mov	[bx],cl
   6.537 +		inc	bx
   6.538 +		inc	ax
   6.539 +		jmp	@@fill
   6.540 +@@filled:
   6.541 +		add	[bp-4-2],ax
   6.542 +		add	[word data],ax
   6.543 +		sub	[word sz],ax
   6.544 +		jz	image_done
   6.545 +		mov	cx,[di+22]		; lo m->chunk_size
   6.546 +		or	cx,[di+24]		; hi m->chunk_size
   6.547 +		jnz	image_done
   6.548 +                or	cx,[di+26]		; m->next_chunk
   6.549 +		jz	image_done
   6.550 +		push	di
   6.551 +                call	cx			; m->next_chunk()
   6.552 +		pop	di
   6.553 +		mov	cx,[di+22]		; lo m->chunk_size
   6.554 +		or	cx,[di+24]		; hi m->chunk_size
   6.555 +		jz	image_done
   6.556 +		jmp	@@loop
   6.557 +
   6.558 +        endp    _read_image
   6.559 +
   6.560 +
   6.561 +;***************************************************************
   6.562 +;unsigned long strtol(const char *s);
   6.563 +;***************************************************************
   6.564 +        global  _strtol:near
   6.565 +        proc    _strtol near
   6.566 +
   6.567 +;TODO NO386
   6.568 +		ifndef	NO386
   6.569 +		pop	ax			;caller return address
   6.570 +                pop	cx			; s
   6.571 +		push	cx
   6.572 +		push	ax
   6.573 +		xor	ebx,ebx
   6.574 +		jcxz	@@end
   6.575 +		push	si
   6.576 +		mov	si,cx
   6.577 +		xor	ecx,ecx
   6.578 +		xor	eax,eax
   6.579 +		mov	cl,10			; radix
   6.580 +		lodsb
   6.581 +		cmp	al,'+'
   6.582 +		je	@@radixskip
   6.583 +		cmp	al,'-'
   6.584 +		clc
   6.585 +		jne	@@radixkeep
   6.586 +		stc
   6.587 +@@radixskip:
   6.588 +		lodsb
   6.589 +@@radixkeep:
   6.590 +		pushf
   6.591 +		cmp	al,'0'
   6.592 +		jne	@@radixok
   6.593 +		mov	cl,8
   6.594 +		lodsb
   6.595 +		mov	dl,20h
   6.596 +		or	dl,al
   6.597 +		cmp	dl,'x'
   6.598 +		jne	@@radixok
   6.599 +		mov	cl,16
   6.600 +@@strtollp:
   6.601 +		lodsb
   6.602 +@@radixok:
   6.603 +		sub	al,'0'
   6.604 +		jb	@@endstrtol
   6.605 +		cmp	al,9
   6.606 +		jbe	@@digitok
   6.607 +		or	al,20h
   6.608 +		cmp	al,'a'-'0'
   6.609 +		jb	@@endstrtol
   6.610 +		sub	al,'a'-'0'-10
   6.611 +@@digitok:
   6.612 +		cmp	al,cl
   6.613 +		jae	@@endstrtol
   6.614 +		xchg	eax,ebx
   6.615 +		mul	ecx
   6.616 +		add	eax,ebx
   6.617 +		xchg	eax,ebx
   6.618 +		jmp	@@strtollp
   6.619 +@@endstrtol:
   6.620 +		mov	cl,10
   6.621 +		cmp	al,'k'-'a'+10
   6.622 +		je	@@shift
   6.623 +		mov	cl,20
   6.624 +		cmp	al,'m'-'a'+10
   6.625 +		je	@@shift
   6.626 +		mov	cl,30
   6.627 +		cmp	al,'g'-'a'+10
   6.628 +		jne	@@noshift
   6.629 +@@shift:
   6.630 +		shl	ebx,cl
   6.631 +@@noshift:
   6.632 +		popf
   6.633 +		jnc	@@end
   6.634 +		neg	ebx
   6.635 +@@end:
   6.636 +		push	ebx
   6.637 +		pop	ax
   6.638 +		pop	dx
   6.639 +popsiret:
   6.640 +		pop	si
   6.641 +		else
   6.642 +		pop	ax			;caller return address
   6.643 +                pop	cx			; s
   6.644 +		push	cx
   6.645 +		push	ax
   6.646 +		push	si
   6.647 +		push	di
   6.648 +		xor	ax,ax
   6.649 +		cwd
   6.650 +		xchg	ax,di
   6.651 +		jcxz	@@end
   6.652 +		mov	si,cx
   6.653 +		mov	cx,10			; radix
   6.654 +		lodsb
   6.655 +		cmp	al,'+'
   6.656 +		je	@@radixskip
   6.657 +		cmp	al,'-'
   6.658 +		clc
   6.659 +		jne	@@radixkeep
   6.660 +		stc
   6.661 +@@radixskip:
   6.662 +		lodsb
   6.663 +@@radixkeep:
   6.664 +		pushf
   6.665 +		cmp	al,'0'
   6.666 +		jne	@@radixok
   6.667 +		mov	cl,8
   6.668 +		lodsb
   6.669 +		mov	ah,20h
   6.670 +		or	ah,al
   6.671 +		cmp	ah,'x'
   6.672 +		jne	@@radixok
   6.673 +		mov	cl,16
   6.674 +@@strtollp:
   6.675 +		lodsb
   6.676 +@@radixok:
   6.677 +		sub	al,'0'
   6.678 +		jb	@@endstrtol
   6.679 +		cmp	al,9
   6.680 +		jbe	@@digitok
   6.681 +		or	al,20h
   6.682 +		cmp	al,'a'-'0'
   6.683 +		jb	@@endstrtol
   6.684 +		sub	al,'a'-'0'-10
   6.685 +@@digitok:
   6.686 +		cmp	al,cl
   6.687 +		jae	@@endstrtol
   6.688 +
   6.689 +		push	ax
   6.690 +		push	si
   6.691 +		push	dx
   6.692 +		xchg	ax,di
   6.693 +		mul	cx
   6.694 +		xchg	ax,di
   6.695 +		xchg	ax,dx
   6.696 +		xchg	ax,si
   6.697 +		pop	ax
   6.698 +		mul	cx
   6.699 +		add	ax,si
   6.700 +		pop	si
   6.701 +		xchg	ax,dx
   6.702 +		pop	ax
   6.703 +		mov	ah,0
   6.704 +		add	di,ax
   6.705 +		adc	dx,0
   6.706 +
   6.707 +		jmp	@@strtollp
   6.708 +@@endstrtol:
   6.709 +		mov	cl,10
   6.710 +		cmp	al,'k'-'a'+10
   6.711 +		je	@@shift
   6.712 +		mov	cl,20
   6.713 +		cmp	al,'m'-'a'+10
   6.714 +		je	@@shift
   6.715 +		mov	cl,30
   6.716 +		cmp	al,'g'-'a'+10
   6.717 +		jne	@@noshift
   6.718 +@@shift:
   6.719 +		rcl	di,1
   6.720 +		shl	dx,1
   6.721 +		loop	@@shift
   6.722 +@@noshift:
   6.723 +		popf
   6.724 +		jnc	@@end
   6.725 +		not	dx
   6.726 +		neg	di
   6.727 +		jne	@@end
   6.728 +		inc	dx
   6.729 +@@end:
   6.730 +		xchg	ax,di
   6.731 +		pop	di
   6.732 +popsiret:
   6.733 +		pop	si
   6.734 +		endif
   6.735 +		ret
   6.736 +
   6.737 +        endp    _strtol
   6.738 +
   6.739 +
   6.740 +;***************************************************************
   6.741 +;>void sort(unsigned long  *base:BX!, size_t nel:CX)
   6.742 +;NO386 safe: only used by VCPI
   6.743 +;***************************************************************
   6.744 +        global  _sort:near
   6.745 +        proc    _sort near
   6.746 +
   6.747 +		pop	ax			;caller return address
   6.748 +                pop	bx			; base
   6.749 +		pop	cx			; nel
   6.750 +		push	cx
   6.751 +		push	bx
   6.752 +		push	ax
   6.753 +        global  sort:near
   6.754 +sort:
   6.755 +	ifndef	fastsort
   6.756 +;  bubble sort
   6.757 +		push	si
   6.758 +		cmp	cx,2
   6.759 +		jl	popsiret
   6.760 +		shl	cx,2
   6.761 +@@loop:
   6.762 +		xor	ax,ax
   6.763 +		jcxz	popsiret
   6.764 +		mov	si,4
   6.765 +@@next:
   6.766 +		mov	edx,[bx+si-4]
   6.767 +		cmp	edx,[bx+si]
   6.768 +		jbe	@@ok
   6.769 +		xchg	edx,[bx+si]
   6.770 +		mov	[bx+si-4],edx
   6.771 +		mov	ax,si
   6.772 +@@ok:
   6.773 +		add	si,4
   6.774 +		cmp	si,cx
   6.775 +		jb	@@next
   6.776 +		xchg	ax,cx
   6.777 +		jmp	@@loop
   6.778 +	else
   6.779 +;  shell sort (c) uclibc GPL
   6.780 +		push	si di
   6.781 +; {
   6.782 +;>	size_t wgap:SI;
   6.783 +;
   6.784 +;	if (nel > 1) {
   6.785 +		cmp	cx,1
   6.786 +		jbe	@@end
   6.787 +;		wgap = 0;
   6.788 +		xor	ax,ax
   6.789 +;		do {
   6.790 +@@wgaplp:
   6.791 +		mov	si,ax
   6.792 +;			wgap = 3 * wgap + 1;
   6.793 +		mov	dx,3
   6.794 +		mul	dx
   6.795 +		inc	ax
   6.796 +;		} while (wgap < (nel-1)/3);
   6.797 +		cmp	ax,cx
   6.798 +		jb	@@wgaplp
   6.799 +;		/* From the above, we know that either wgap == 1 < nel or */
   6.800 +;		/* ((wgap-1)/3 < (int) ((nel-1)/3) <= (nel-1)/3 ==> wgap <  nel. */
   6.801 +;		wgap *= 4;			/* So this can not overflow if wnel doesn't. */
   6.802 +		shl	si,2
   6.803 +;		nel *= 4;			/* Convert nel to 'wnel' */
   6.804 +		shl	cx,2
   6.805 +;		do {
   6.806 +@@lp1:
   6.807 +;>	                size_t i:DI;
   6.808 +;			i = wgap;
   6.809 +		mov	di,si
   6.810 +;			do {
   6.811 +@@lp2:
   6.812 +;>	                	size_t j:DX;
   6.813 +;				j = i;
   6.814 +		mov	dx,di
   6.815 +;				do {
   6.816 +@@lp3:
   6.817 +;>					register char *a:BX!;
   6.818 +;
   6.819 +;					j -= wgap;
   6.820 +		sub	dx,si
   6.821 +;					a = j + ((char *)base);
   6.822 +		push	bx
   6.823 +		add	bx,dx
   6.824 +;					if (cmp(a, a + wgap) <= 0) {
   6.825 +		mov	eax,[bx]
   6.826 +		cmp	eax,[bx+si]
   6.827 +		jbe	@@brk3
   6.828 +;						break;
   6.829 +;					}
   6.830 +		xchg	eax,[bx+si]
   6.831 +		mov	[bx],eax
   6.832 +;					swap(a, a + wgap);
   6.833 +		pop	bx
   6.834 +;				} while (j >= wgap);
   6.835 +		cmp	dx,si
   6.836 +		jae	@@lp3
   6.837 +		push	bx
   6.838 +@@brk3:
   6.839 +		pop	bx
   6.840 +;				i += 4;
   6.841 +		add	di,4
   6.842 +;			} while (i < nel);
   6.843 +		cmp	di,cx
   6.844 +		jb	@@lp2
   6.845 +;			wgap = (wgap - 4)/3;
   6.846 +		sub	si,4
   6.847 +		xchg	ax,si
   6.848 +		cwd
   6.849 +		mov	si,3
   6.850 +		div	si	; kill dx
   6.851 +		xchg	ax,si
   6.852 +;		} while (wgap);
   6.853 +		or	si,si
   6.854 +		jnz	@@lp1
   6.855 +@@end:
   6.856 +;	}
   6.857 +;}
   6.858 +		pop	di si
   6.859 +		ret
   6.860 +endif
   6.861 +
   6.862 +        endp    _sort
   6.863 +
   6.864 +
   6.865 +;***************************************************************
   6.866 +;void* malloc(unsigned sz);
   6.867 +;***************************************************************
   6.868 +        global  _malloc:near
   6.869 +        proc    _malloc near
   6.870 +
   6.871 +		pop	ax			;caller return address
   6.872 +                pop	cx			; sz
   6.873 +		push	cx
   6.874 +		push	ax
   6.875 +        global  malloc:near			; malloc(cx)
   6.876 +malloc:
   6.877 +		mov	ax,[_heap_top]
   6.878 +		mov	bx,sp
   6.879 +		sub	bh,14h			; MIN_STACK=_1k+PAGE_SIZE
   6.880 +		sub	bx,cx
   6.881 +		jb	@@outofmem
   6.882 +		cmp	bx,ax
   6.883 +		jb	@@outofmem
   6.884 +		add	[_heap_top],cx		; _BEG has zero'd heap
   6.885 +		;mov	bx,ax
   6.886 +@@zalloc:
   6.887 +		;mov	[byte bx],0
   6.888 +		;inc	bx			; ZF=0
   6.889 +		;loop	@@zalloc
   6.890 +		ret
   6.891 +@@outofmem:
   6.892 +		mov	bx,offset msg_malloc
   6.893 +		call	puts
   6.894 +		xor	ax,ax			; ZF=1
   6.895 +		ret
   6.896 +
   6.897 +        endp    _malloc
   6.898 +
   6.899 +
   6.900 +		ifdef	NO386
   6.901 +;***************************************************************
   6.902 +;u16 topseg();
   6.903 +;***************************************************************
   6.904 +        global  _topseg:near
   6.905 +        proc    _topseg near
   6.906 +
   6.907 +		int	12h
   6.908 +		jnc	@@max640k
   6.909 +		mov	ax,640			; 9000
   6.910 +@@max640k:
   6.911 +		sub	al,040h
   6.912 +		and	al,0C0h
   6.913 +		mov	cl,6
   6.914 +		shl	ax,cl
   6.915 +		ret
   6.916 +
   6.917 +        endp    _topseg
   6.918 +		endif
   6.919 +
   6.920 +
   6.921 +        ends    _TEXT
   6.922 +
   6.923 +        end
   6.924 +
   6.925 +;###### END OF FILE ############################################
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/linld/stuff/src/CRTL.H	Tue Nov 22 21:19:01 2016 +0100
     7.3 @@ -0,0 +1,53 @@
     7.4 +// This file is distributed under GPL
     7.5 +//
     7.6 +// Bare bones of C runtime library
     7.7 +
     7.8 +#define MK_FP(seg,ofs) ((void _seg *)(seg) + (void near *)(ofs))
     7.9 +#define FP_SEG(fp)     ((unsigned) (void _seg*) (void far*)(fp))
    7.10 +#define FP_OFF(fp)     ((unsigned) (fp))
    7.11 +
    7.12 +const unsigned MIN_STACK = 0x400;
    7.13 +const unsigned MAX_MALLOC = 0xF000;
    7.14 +
    7.15 +const O_RDONLY = 0;     // for open()
    7.16 +const O_BINARY = 0;
    7.17 +
    7.18 +const SEEK_SET = 0;     // for lseek()
    7.19 +const SEEK_CUR = 1;
    7.20 +const SEEK_END = 2;
    7.21 +
    7.22 +extern char text_start; extern char text_end;
    7.23 +extern char data_start; extern char data_end;
    7.24 +extern char bss_start;  extern char bss_end;
    7.25 +extern char* heap_top;
    7.26 +
    7.27 +extern int ximage_size, ximage_fd;
    7.28 +
    7.29 +void parse_cmdline();
    7.30 +extern "C" int strlen(const char* s);
    7.31 +extern "C" int strhead(const char* a,const char* b);
    7.32 +extern "C" int open(const char* name, int flags);
    7.33 +extern "C" int close(int fd);
    7.34 +extern "C" void exit(int n);
    7.35 +extern "C" void abort();
    7.36 +extern "C" int read(int fd, void* data, int sz);
    7.37 +extern "C" int write(int fd, const void* data, int sz);
    7.38 +extern "C" long lseek(int fd, long sz, int dir);
    7.39 +extern "C" long rewind(int fd);
    7.40 +extern "C" void* malloc(unsigned sz);
    7.41 +extern "C" void puts(const char* s);
    7.42 +extern "C" void putsz(const char* s);
    7.43 +extern "C" unsigned long strtol(const char *s);
    7.44 +
    7.45 +// Extensions
    7.46 +//static void barrier() {}
    7.47 +//static void cli() { asm { cli } }
    7.48 +//static void sti() { asm { sti } }
    7.49 +#define barrier() do {} while(0)
    7.50 +#define cli() do { asm { cli } } while(0)
    7.51 +#define sti() do { asm { sti } } while(0)
    7.52 +#define int3() do { asm { db 0cch } } while(0)
    7.53 +#define nop() do { asm { db 90h } } while(0)
    7.54 +extern char no_exit;
    7.55 +extern "C" int die(const char* msg);
    7.56 +extern "C" char* malloc_or_die(unsigned size);
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/linld/stuff/src/CRTLX.ASM	Tue Nov 22 21:19:01 2016 +0100
     8.3 @@ -0,0 +1,401 @@
     8.4 +;***************************************************************
     8.5 +;****** This file is distributed under GPL
     8.6 +;***************************************************************
     8.7 +                ideal
     8.8 +                %crefref
     8.9 +                %noincl
    8.10 +                %nomacs
    8.11 +                p386
    8.12 +
    8.13 +        group   DGROUP  _TEXT,_DATA,_BSS
    8.14 +        assume  cs:DGROUP,ds:DGROUP
    8.15 +
    8.16 +        segment _DATA byte public use16 'DATA'
    8.17 +        ends    _DATA
    8.18 +
    8.19 +        segment _BSS byte public use16 'BSS'
    8.20 +
    8.21 +ultoabuf	db	12	dup (?)
    8.22 +
    8.23 +        ends    _BSS
    8.24 +
    8.25 +        segment _TEXT byte public use16 'CODE'
    8.26 +
    8.27 +;***************************************************************
    8.28 +;char* strcpy(const char* a,const char* b);
    8.29 +;***************************************************************
    8.30 +        global  _strcpy:near
    8.31 +        proc    _strcpy near
    8.32 +
    8.33 +		mov	dl,0
    8.34 +cat:
    8.35 +		pop	cx			;caller return address
    8.36 +                pop	ax			; a
    8.37 +                pop	bx			; b
    8.38 +                push	bx
    8.39 +                push	ax
    8.40 +                push	cx
    8.41 +                push	ax si
    8.42 +                xchg	ax,si
    8.43 +		shr	dl,1
    8.44 +		jnc	@@nocat
    8.45 +@@catlp:
    8.46 +		lodsb
    8.47 +		cmp	al,0
    8.48 +                jne	@@catlp
    8.49 +		dec	si
    8.50 +@@nocat:
    8.51 +                sub	bx,si
    8.52 +@@cpylp:
    8.53 +                mov	al,[bx+si]
    8.54 +		test	dl,1
    8.55 +		jnz	@@nocpy
    8.56 +                mov	[si],al
    8.57 +                inc	si
    8.58 +		cmp	al,0
    8.59 +                jne	@@cpylp
    8.60 +                pop	si ax
    8.61 +                ret
    8.62 +@@nocpy:
    8.63 +                sub	al,[si]
    8.64 +		jnz	@@out
    8.65 +                lodsb
    8.66 +		cmp	al,0
    8.67 +                jne	@@cpylp
    8.68 +@@out:
    8.69 +		cbw
    8.70 +                pop	si dx
    8.71 +                ret
    8.72 +
    8.73 +        endp    _strcpy
    8.74 +
    8.75 +
    8.76 +;***************************************************************
    8.77 +;char* strcat(const char* a,const char* b);
    8.78 +;***************************************************************
    8.79 +        global  _strcat:near
    8.80 +        proc    _strcat near
    8.81 +
    8.82 +		mov	dl,1
    8.83 +                jmp	cat
    8.84 +
    8.85 +        endp    _strcat
    8.86 +
    8.87 +
    8.88 +;***************************************************************
    8.89 +;int strcmp(const char* a,const char* b);
    8.90 +;***************************************************************
    8.91 +        global  _strcmp:near
    8.92 +        proc    _strcmp near
    8.93 +
    8.94 +		mov	dl,2
    8.95 +                jmp	cat
    8.96 +
    8.97 +        endp    _strcmp
    8.98 +
    8.99 +
   8.100 +;***************************************************************
   8.101 +;char strstr(const char* a,const char* b);
   8.102 +;***************************************************************
   8.103 +        global  _strstr:near
   8.104 +        proc    _strstr near
   8.105 +
   8.106 +		pop	ax			;caller return address
   8.107 +                pop	bx			; a
   8.108 +                pop	dx			; b
   8.109 +                push	dx
   8.110 +                push	bx
   8.111 +                push	ax
   8.112 +                push	di
   8.113 +@@loop:
   8.114 +		xor	ax,ax
   8.115 +		cmp	[bx],al
   8.116 +		jz	@@end
   8.117 +		mov	cx,bx
   8.118 +		mov	di,dx
   8.119 +		sub	di,bx
   8.120 +@@match:
   8.121 +		mov	al,[bx+di]
   8.122 +		or	al,al
   8.123 +		jz	@@found
   8.124 +		inc	bx
   8.125 +		cmp	al,[bx-1]
   8.126 +		jnz	@@loop
   8.127 +		jmp	@@match
   8.128 +@@found:
   8.129 +		xchg	ax,cx
   8.130 +@@end:
   8.131 +                pop	di
   8.132 +		ret
   8.133 +
   8.134 +        endp    _strstr
   8.135 +
   8.136 +
   8.137 +;***************************************************************
   8.138 +;int cpuhaslm(void)
   8.139 +;***************************************************************
   8.140 +        global  _cpuhaslm:near
   8.141 +        proc    _cpuhaslm near
   8.142 +
   8.143 +		pushf
   8.144 +; Check for oldies
   8.145 +		mov	ax, 0F000h
   8.146 +		push	ax		; < 286 : flags[12..15] are forced 1
   8.147 +		popf			; = 286 : flags[12..15] are forced 0
   8.148 +		pushf			; > 286 : only flags[15] is forced 0
   8.149 +		pop	dx
   8.150 +		popf
   8.151 +		add	dh,ah		; NS=386+, NC=286
   8.152 +		cbw
   8.153 +		clc
   8.154 +                js     @@bad   		;it is a 86/186/286, not a 386+
   8.155 +		pushfd
   8.156 +		pushfd
   8.157 +		pop	ebx
   8.158 +		mov	ecx,ebx
   8.159 +		xor	ebx,00100000h	; toggle CPUID feature bit 21
   8.160 +		push	ebx
   8.161 +		popfd
   8.162 +		pushfd
   8.163 +		pop	ebx
   8.164 +		popfd
   8.165 +		xor	ebx,ecx
   8.166 +		shr	ebx,1+21	; CPUID feature bit ?
   8.167 +		jnc	@@bad
   8.168 +		mov	eax,80000001h	; Extended Processor Info and Feature Bits
   8.169 +		db	0Fh,0A2h	; cpuid
   8.170 +		xor	ax,ax
   8.171 +		shr	edx,1+29	; LM feature bit ?
   8.172 +@@bad:
   8.173 +		sbb	ax,ax
   8.174 +		ret
   8.175 +
   8.176 +        endp    _cpuhaslm
   8.177 +
   8.178 +
   8.179 +;***************************************************************
   8.180 +;char *progname(void)
   8.181 +;***************************************************************
   8.182 +        global  _progname:near
   8.183 +        proc    _progname near
   8.184 +
   8.185 +		push	si di es
   8.186 +		mov	ah,30h
   8.187 +		int	21h
   8.188 +		cmp	al,3
   8.189 +		mov	ax,0
   8.190 +		jb	@@skip
   8.191 +		mov	es,[cs:2Ch]
   8.192 +		mov	cx,-1
   8.193 +		xor	di,di
   8.194 +		xor	al,al
   8.195 +@@loop1:
   8.196 +		repne
   8.197 +		  scasb
   8.198 +		scasb
   8.199 +		jne	@@loop1
   8.200 +		lea	si,[di+2]
   8.201 +		mov	bx, si
   8.202 +		extrn	strlen:near
   8.203 +		call	near strlen
   8.204 +		xchg	ax,cx
   8.205 +		inc	cx
   8.206 +		extrn	malloc_or_die:near
   8.207 +		call	near malloc_or_die
   8.208 +		xchg	ax,di
   8.209 +		push	ds
   8.210 +		push	ds
   8.211 +		push	es
   8.212 +		pop	ds
   8.213 +		pop	es
   8.214 +		push	di
   8.215 +@@loop2:
   8.216 +		lodsb
   8.217 +		stosb
   8.218 +		or	al,al
   8.219 +		jnz	@@loop2
   8.220 +		pop	ax
   8.221 +		pop	ds
   8.222 +@@skip:
   8.223 +		pop	es di si
   8.224 +		ret
   8.225 +
   8.226 +        endp    _progname
   8.227 +
   8.228 +
   8.229 +;***************************************************************
   8.230 +;int chdir(char *path);
   8.231 +;***************************************************************
   8.232 +        global  _chdir:near
   8.233 +        proc    _chdir near
   8.234 +
   8.235 +		pop	ax
   8.236 +		pop	dx
   8.237 +		push	dx
   8.238 +		push	ax
   8.239 +chdir:
   8.240 +		stc
   8.241 +		mov	ax,713Bh
   8.242 +		int	21h
   8.243 +		jnc	@@end
   8.244 +		mov	ah,3Bh
   8.245 +		int	21h
   8.246 +@@end:
   8.247 +		sbb	ax,ax
   8.248 +		ret
   8.249 +
   8.250 +        endp    _chdir
   8.251 +
   8.252 +
   8.253 +;***************************************************************
   8.254 +;int chdirname(char *path)
   8.255 +;***************************************************************
   8.256 +        global  _chdirname:near
   8.257 +        proc    _chdirname near
   8.258 +
   8.259 +		pop	ax
   8.260 +		pop	bx
   8.261 +		push	bx
   8.262 +		push	ax
   8.263 +
   8.264 +		cmp	[byte bx+1],3Ah
   8.265 +		jne	@@nodisk
   8.266 +		mov	dl,[bx]
   8.267 +		or	dl,20h
   8.268 +		sub	dl,61h
   8.269 +		mov	ah,0Eh
   8.270 +		push	bx
   8.271 +		int	21h
   8.272 +		pop	bx
   8.273 +		inc	bx
   8.274 +		inc	bx
   8.275 +@@nodisk:
   8.276 +		mov	dx,bx
   8.277 +		xor	cx,cx
   8.278 +@@next:
   8.279 +		mov	al,[bx]
   8.280 +		cmp	al,5Ch
   8.281 +		jne	@@tsteos
   8.282 +		mov	cx,bx
   8.283 +@@tsteos:
   8.284 +		inc	bx
   8.285 +		or	al,al
   8.286 +		jnz	@@next
   8.287 +		cbw
   8.288 +		jcxz	@@end
   8.289 +		mov	bx,cx
   8.290 +		push	[word bx]
   8.291 +		mov	[bx],al
   8.292 +		push	bx
   8.293 +		call	chdir
   8.294 +		pop	bx
   8.295 +		pop	[word bx]
   8.296 +@@end:
   8.297 +		ret
   8.298 +
   8.299 +        endp    _chdirname
   8.300 +
   8.301 +
   8.302 +;***************************************************************
   8.303 +;char *ultoa(unsigned long n);
   8.304 +;***************************************************************
   8.305 +        global  _ultoa:near
   8.306 +        proc    _ultoa near
   8.307 +
   8.308 +		pop	ax
   8.309 +		pop	cx
   8.310 +		pop	dx
   8.311 +		push	dx
   8.312 +		push	cx
   8.313 +		push	ax		; DX:CX = n
   8.314 +		push	si
   8.315 +		mov	si,10
   8.316 +		mov	bx,offset ultoabuf+11
   8.317 +@@loop:
   8.318 +		dec	bx
   8.319 +		xchg	ax,dx
   8.320 +		xor	dx,dx
   8.321 +		div	si		; DX:AX = 0000:hi(n)
   8.322 +		xchg	ax,cx		; CX = hi(n)/10
   8.323 +		div	si		; DX:AX = hi(n)%10:lo(n)
   8.324 +		xchg	ax,cx		; CX = lo(n/10)
   8.325 +		xchg	ax,dx		; DX = hi(n)/10 = hi(n/10)
   8.326 +		add	al,'0'
   8.327 +		mov	[bx],al
   8.328 +		mov	ax,cx
   8.329 +		or	ax,dx
   8.330 +		jnz	@@loop
   8.331 +		xchg	ax,bx
   8.332 +		pop	si
   8.333 +		ret
   8.334 +
   8.335 +        endp    _ultoa
   8.336 +
   8.337 +
   8.338 +;***************************************************************
   8.339 +;unsigned long kver2ul(char *kernel_version);
   8.340 +;***************************************************************
   8.341 +        global  _kver2ul:near
   8.342 +        proc    _kver2ul near
   8.343 +
   8.344 +		pop	ax
   8.345 +		pop	dx
   8.346 +		push	dx
   8.347 +		push	ax
   8.348 +		push	bp si di
   8.349 +		xor	di,di
   8.350 +		push	di
   8.351 +		push	di
   8.352 +		mov	bp,sp
   8.353 +		mov	si,dx
   8.354 +		inc	di
   8.355 +		inc	di
   8.356 +		mov	cl,4
   8.357 +@@number:
   8.358 +		xor	ax,ax
   8.359 +@@digit:
   8.360 +		shl	al,cl
   8.361 +		shl	ax,cl
   8.362 +		lodsb
   8.363 +		sub	al,30h
   8.364 +		cmp	al,9
   8.365 +		jbe	@@digit
   8.366 +		mov	[bp+di],ah
   8.367 +		dec	di
   8.368 +		jns	@@number
   8.369 +		pop	ax
   8.370 +		pop	dx
   8.371 +		pop	di si bp
   8.372 +		ret
   8.373 +
   8.374 +        endp    _kver2ul
   8.375 +
   8.376 +        global  N_LXURSH@:near
   8.377 +        proc    N_LXURSH@ near
   8.378 +
   8.379 +		mov	ch,0
   8.380 +@@loop:
   8.381 +		shr	dx,1
   8.382 +		rcr	ax,1
   8.383 +		loop	@@loop
   8.384 +		ret
   8.385 +
   8.386 +        endp    N_LXURSH@
   8.387 +
   8.388 +        global  N_LXLSH@:near
   8.389 +        proc    N_LXLSH@ near
   8.390 +
   8.391 +		mov	ch,0
   8.392 +@@loop:
   8.393 +		shl	ax,1
   8.394 +		rcl	dx,1
   8.395 +		loop	@@loop
   8.396 +		ret
   8.397 +
   8.398 +        endp    N_LXLSH@
   8.399 +
   8.400 +        ends    _TEXT
   8.401 +
   8.402 +        end
   8.403 +
   8.404 +;###### END OF FILE ############################################
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/linld/stuff/src/CRTLX.H	Tue Nov 22 21:19:01 2016 +0100
     9.3 @@ -0,0 +1,13 @@
     9.4 +// This file is distributed under GPL
     9.5 +//
     9.6 +#define NULL 0
     9.7 +extern "C" char* strstr(const char* a,const char* b);
     9.8 +extern "C" char* strcat(const char* a,const char* b);
     9.9 +extern "C" char* strcpy(const char* a,const char* b);
    9.10 +extern "C" int strcmp(const char* a,const char* b);
    9.11 +extern "C" int cpuhaslm();
    9.12 +extern "C" char *progname(void);
    9.13 +extern "C" int chdir(char *path);
    9.14 +extern "C" int chdirname(char *path);
    9.15 +extern "C" unsigned long kver2ul(char *kernel_version);
    9.16 +extern "C" char *ultoa(unsigned long n);
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/linld/stuff/src/HIMEM.CPP	Tue Nov 22 21:19:01 2016 +0100
    10.3 @@ -0,0 +1,96 @@
    10.4 +// This file is distributed under GPL
    10.5 +//
    10.6 +// High mem handling routines
    10.7 +// C++ part of VCPI madness is here
    10.8 +
    10.9 +#include "crtl.h"
   10.10 +#include "common.h"
   10.11 +
   10.12 +// Returns physical addr of allocated himem chunk
   10.13 +// Never fails (will use fallback if not enough mem/no xmm)
   10.14 +// TODO: with proper cleanup it is possible to exit to DOS
   10.15 +// even after XMM alloc - do dealloc, then exit...
   10.16 +// don't forget to clean up the mess then, especially
   10.17 +// XMM handle which is lost inside xmm_alloc()...
   10.18 +// (don't drop fallback: use it if no XMM driver detected)
   10.19 +static void read2mem(struct image_himem *m) {
   10.20 +    u32 buf=m->buf;
   10.21 +    while(1) {
   10.22 +	u8 xfer_buf[PAGE_SIZE];
   10.23 +        u16 size = read_image(m, xfer_buf, sizeof(xfer_buf));
   10.24 +        if(s16(size) <= 0) break;
   10.25 +        memcpy32(0, buf, seg(xfer_buf), ofs(xfer_buf), size);
   10.26 +        buf += size;
   10.27 +        m->remaining -= size;
   10.28 +    }
   10.29 +}
   10.30 +
   10.31 +extern "C" void sort(u32* v, int size);
   10.32 +
   10.33 +// Returns ptr to mallocated zero-terminated list of physical page addrs
   10.34 +// Never fails (will die if not enough mem)
   10.35 +// Addresses are sorted in ascending order
   10.36 +// static void malloc_vcpi(struct image_himem *m) {
   10.37 +static void read2vcpi(struct image_himem *m) {
   10.38 +    u16 cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
   10.39 +    u32* bufv = (u32*)malloc_or_die((cnt+1)*sizeof(u32));
   10.40 +    // our malloc zeroes allocated mem: buf[cnt]=0;
   10.41 +    // Allocate pages, storing addrs in addrbuf
   10.42 +    {for(int i=0;i<cnt;i++) {
   10.43 +        u32 v;
   10.44 +        asm {
   10.45 +                db      66h
   10.46 +                xor     dx,dx
   10.47 +                mov     ax,0DE04h
   10.48 +                int     67h
   10.49 +                db      66h
   10.50 +                mov     [word ptr v],dx
   10.51 +        }
   10.52 +        extern const char vcpi_alloc_err[];
   10.53 +        if(!v) die(vcpi_alloc_err);
   10.54 +        bufv[i] = v;
   10.55 +    }}
   10.56 +    // Sanitize addresses: ascending sort
   10.57 +    sort(bufv,cnt);
   10.58 +    m->bufv = bufv;
   10.59 +//}
   10.60 +
   10.61 +// Reads opened fd data into malloc_vcpi'ed memory
   10.62 +// Dies if file isn't exactly 'size' bytes long
   10.63 +// Needs intermediate buffer of exactly Nx4k bytes
   10.64 +// static void read2vcpi(struct image_himem *m) {
   10.65 +    while(1) {
   10.66 +	u8 xfer_buf[PAGE_SIZE];
   10.67 +        u16 size = read_image(m, xfer_buf, PAGE_SIZE);
   10.68 +        if(s16(size) <= 0 || !*bufv) break;
   10.69 +        m->remaining -= size;
   10.70 +        memcpy_vcpi(*bufv++, seg(xfer_buf), ofs(xfer_buf));
   10.71 +    }
   10.72 +}
   10.73 +
   10.74 +void init_vcpi() {
   10.75 +    heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
   10.76 +    get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
   10.77 +}
   10.78 +
   10.79 +int skip_xmmalloc;
   10.80 +void load_image(struct image_himem *m) {
   10.81 +    no_exit++;       // die() won't return to DOS
   10.82 +    m->remaining = m->size;
   10.83 +    m->buf = m->fallback;
   10.84 +    if(m->fallback < _1m) {
   10.85 +        read2mem(m);
   10.86 +    } else if(vcpi==0) {
   10.87 +	if (!skip_xmmalloc) {
   10.88 +        	u32 v = xmm_alloc(m->size);
   10.89 +        	if(v) m->buf = v;
   10.90 +	}
   10.91 +        read2mem(m);
   10.92 +    } else {
   10.93 +        //malloc_vcpi(m);
   10.94 +        read2vcpi(m);
   10.95 +    }
   10.96 +    if(m->remaining) die("Read error");
   10.97 +//break iso case    close(m->fd);
   10.98 +}
   10.99 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/linld/stuff/src/ISO9660.CPP	Tue Nov 22 21:19:01 2016 +0100
    11.3 @@ -0,0 +1,172 @@
    11.4 +#include "crtl.h"
    11.5 +#include "crtlx.h"
    11.6 +#include "iso9660.h"
    11.7 +#define __ROCKRIDGE
    11.8 +
    11.9 +char *isofilename;
   11.10 +unsigned long isofileofs, isofilesize;
   11.11 +unsigned short isofilemod;
   11.12 +int isofd;
   11.13 +
   11.14 +#define SECTORSZ 2048
   11.15 +#define SECTORBITS 11
   11.16 +static char buffer[SECTORSZ];
   11.17 +
   11.18 +static int readsector(unsigned long offset)
   11.19 +{
   11.20 +	return (lseek(isofd, offset, SEEK_SET) != -1
   11.21 +		    && read(isofd, buffer, SECTORSZ) == SECTORSZ);
   11.22 +}
   11.23 +
   11.24 +int isoread(char *data, unsigned size)
   11.25 +{
   11.26 +	int get, n;
   11.27 +	
   11.28 +	if (size > isofilesize)
   11.29 +		size = isofilesize;
   11.30 +	if (lseek(isofd, isofileofs, SEEK_SET) == -1)
   11.31 +		return -1;
   11.32 +	for (get = size; get; get -= n, data += n) {
   11.33 +		n = read(isofd,data,get);
   11.34 +		if (n < 0)
   11.35 +			return n;
   11.36 +		if (n == 0)
   11.37 +			break;
   11.38 +		isofileofs += n;
   11.39 +		isofilesize -= n;
   11.40 +	}
   11.41 +	return size - get;
   11.42 +}
   11.43 +
   11.44 +static unsigned long isodirofs, isodirsize;
   11.45 +int isoreset(char *name)
   11.46 +{
   11.47 +	if (name)
   11.48 +		isofd = open(name, O_RDONLY);
   11.49 +	if (!readsector(16UL * 2048) || strhead(buffer+1,"CD001")) {
   11.50 +		//close(isofd);
   11.51 +		return -1;
   11.52 +	}
   11.53 +	isodirofs = * (unsigned long *) (buffer + 0x9E);
   11.54 +	isodirofs <<= SECTORBITS;
   11.55 +	isodirsize = * (unsigned long *) (buffer + 0xA6);
   11.56 +	return 0;
   11.57 +}
   11.58 +
   11.59 +int isoreaddir(int restart)
   11.60 +{
   11.61 +	static unsigned long pos, dirofs, dirsize;
   11.62 +	static char dots[] = "..";
   11.63 +	int size, n;
   11.64 +#ifdef __ROCKRIDGE
   11.65 +	char *endname;
   11.66 +#endif
   11.67 +
   11.68 +	if (restart) {
   11.69 +		dirofs = isodirofs;
   11.70 +		dirsize = isodirsize;
   11.71 +		pos = SECTORSZ;
   11.72 +	}
   11.73 +	if (pos >= SECTORSZ || * (short *) (buffer + pos) == 0) {
   11.74 +		if (dirsize < SECTORSZ) return -1;
   11.75 +		readsector(dirofs);
   11.76 +		dirofs += SECTORSZ;
   11.77 +		dirsize -= SECTORSZ;
   11.78 +		pos = 0;
   11.79 +	}
   11.80 +	size = * (short *) (buffer + pos);
   11.81 +	if (size == 0)
   11.82 +		return -1;
   11.83 +	isofileofs = (* (unsigned long *) (buffer + pos + 2)) << SECTORBITS;
   11.84 +	isofilesize = * (unsigned long *) (buffer + pos + 10);
   11.85 +	isofilemod = (buffer[pos + 25] & 2) ? 0040755 : 0100755;
   11.86 +#ifdef __ROCKRIDGE
   11.87 +	endname = NULL;
   11.88 +	n = (buffer[pos + 32] + pos + 34) & -2;
   11.89 +	do {
   11.90 +		int len = buffer[n + 2];
   11.91 +		switch (* (short *) (buffer + n)) {
   11.92 +		case 0x4D4E: // NM
   11.93 +			isofilename = buffer + n + 5;
   11.94 +			endname = buffer + n + len;
   11.95 +			break;
   11.96 +		case 0x5850: // PX
   11.97 +			isofilemod = * (short *) (buffer + n + 4);
   11.98 +			break;
   11.99 +		}
  11.100 +		n += len;
  11.101 +	}
  11.102 +	while (n + 2 < pos + size);
  11.103 +	if (endname)
  11.104 +		*endname = 0;
  11.105 +	else
  11.106 +#endif
  11.107 +	{
  11.108 +		isofilename = buffer + pos + 33;
  11.109 +		switch (* (short *) (isofilename - 1)) {
  11.110 +		case 0x0101:
  11.111 +			isofilename = dots;
  11.112 +			break;
  11.113 +		case 0x0001:
  11.114 +			isofilename = dots + 1;
  11.115 +			break;
  11.116 +		default:
  11.117 +			n = isofilename[-1];
  11.118 +			if (* (short *) (isofilename + n - 2) == 0x313B)
  11.119 +				n -= 2; // remove ;1
  11.120 +			if (isofilename[n - 1] == '.') n--;
  11.121 +			isofilename[n] = 0;
  11.122 +		}
  11.123 +	}
  11.124 +	pos += size;
  11.125 +	return 0;
  11.126 +}
  11.127 +
  11.128 +#define IS_DIR(x)( ((x) & ~0777) == 040000)
  11.129 +int isoopen(char *filename)
  11.130 +{
  11.131 +	int restart;
  11.132 +	char *name, *s, c;
  11.133 +	int _64bits = cpuhaslm();
  11.134 +
  11.135 +retry32:
  11.136 +	name = filename;
  11.137 +	while (*name == '/') {
  11.138 +		name++;
  11.139 +		isoreset(NULL);
  11.140 +	}
  11.141 +	s = name;
  11.142 +	while (1) {
  11.143 +		while (*s && *s != '/') s++;
  11.144 +		c = *s;
  11.145 +		*s = 0;
  11.146 +		for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
  11.147 +			char *n = name, *i = isofilename;
  11.148 +			if (_64bits) {
  11.149 +				int len = strlen(name);
  11.150 +				if (strhead(isofilename, name)) continue;
  11.151 +				n = "64";
  11.152 +				i += len;
  11.153 +			}
  11.154 +			if (strcmp(n, i)) continue;
  11.155 +			if (IS_DIR(isofilemod)) {
  11.156 +				isodirofs = isofileofs;
  11.157 +				isodirsize = isofilesize;
  11.158 +				if (c) {
  11.159 +					*s++ = c;
  11.160 +					name = s;
  11.161 +					goto next;
  11.162 +				}
  11.163 +			}
  11.164 +			lseek(isofd, isofileofs, SEEK_SET);
  11.165 +			return 0;
  11.166 +		}
  11.167 +		if (_64bits) {
  11.168 +			_64bits = 0;
  11.169 +			*s = c;
  11.170 +			goto retry32;
  11.171 +		}
  11.172 +		return -1;
  11.173 +	  next: ;
  11.174 +	}
  11.175 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/linld/stuff/src/ISO9660.H	Tue Nov 22 21:19:01 2016 +0100
    12.3 @@ -0,0 +1,12 @@
    12.4 +#ifndef __ISO9660_H
    12.5 +#define __ISO9660_H
    12.6 +extern char *isofilename;
    12.7 +extern unsigned long isofileofs, isofilesize;
    12.8 +extern unsigned short isofilemod;
    12.9 +extern int isofd;
   12.10 +extern int isoreset(char *name);
   12.11 +extern int isoopen(char *name);
   12.12 +extern int isoreaddir(int restart);
   12.13 +extern int isoread(char *data, unsigned size);
   12.14 +#define isolabel() do { isofileofs=0x8028; isofilesize=32; } while (0)
   12.15 +#endif
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/linld/stuff/src/JUMP.ASM	Tue Nov 22 21:19:01 2016 +0100
    13.3 @@ -0,0 +1,133 @@
    13.4 +;***************************************************************
    13.5 +;****** This file is distributed under GPL
    13.6 +;***************************************************************
    13.7 +                ideal
    13.8 +                %crefref
    13.9 +                %noincl
   13.10 +                %nomacs
   13.11 +                p386
   13.12 +
   13.13 +        group   DGROUP  _TEXT,_BSS
   13.14 +        assume  cs:DGROUP,ds:DGROUP
   13.15 +
   13.16 +        segment _BSS byte public use16 'BSS'
   13.17 +
   13.18 +        global  _pm_high:byte
   13.19 +        global  _pm:dword
   13.20 +
   13.21 +        ends    _BSS
   13.22 +
   13.23 +
   13.24 +        segment _TEXT byte public use16 'CODE'
   13.25 +
   13.26 +;***************************************************************
   13.27 +;void set_sregs_jump_seg_ofs(u32 csip, u32 sssp);
   13.28 +;****** Never returns
   13.29 +;***************************************************************
   13.30 +        global  _set_sregs_jump_seg_ofs:near
   13.31 +        proc    _set_sregs_jump_seg_ofs near
   13.32 +
   13.33 +		extrn	dos_shutdown:near
   13.34 +
   13.35 +		pop	ax			;caller return address
   13.36 +		test	[byte _pm_high],-1	; load high ? clear CF
   13.37 +		jne	isbzimage
   13.38 +		; finish loading
   13.39 +		extrn   @last_ditch$qv:near
   13.40 +		push	cs
   13.41 +		call	@last_ditch$qv
   13.42 +		mov	bx,[word _pm+2+2]	; get pm->fallback high word
   13.43 +		; self move
   13.44 +		cld
   13.45 +	;	push	9940h			; 5120 bytes for cmdline
   13.46 +	push	9820h			; 512 bytes for cmdline
   13.47 +		pop	es			; min 1024 bytes for stack
   13.48 +		xor	si,si			;  A000 -9400 -0800(>movedend)
   13.49 +		xor	di,di			; set ZF
   13.50 +	;	mov	cx,offset movedend
   13.51 +        global  _bss_end:byte
   13.52 +	mov	cx,offset _bss_end
   13.53 +		rep
   13.54 +		  movsb
   13.55 +		push	es
   13.56 +		call	near doretf		; mov cs,es
   13.57 +		stc
   13.58 +isbzimage:
   13.59 +		pop	cx			; ip
   13.60 +		pop	dx			; cs
   13.61 +		pop	ax			; sp
   13.62 +		pop	ss			; ss
   13.63 +		xchg	sp,ax
   13.64 +		push	dx cx
   13.65 +		jnc	nomove
   13.66 +		push	cs
   13.67 +		pop	ds
   13.68 +		call	near dos_shutdown
   13.69 +		; move zImage pm
   13.70 +		mov	ax,8
   13.71 +		cwd
   13.72 +		cmp	bx,ax
   13.73 +		jnb	bufhigh
   13.74 +		sub	ax,bx
   13.75 +		inc	ax
   13.76 +bufhigh:
   13.77 +		push	ax
   13.78 +		push	dx			; size=up to 512k
   13.79 +		push	bx			; src ofs= pm.fallback
   13.80 +		push	dx
   13.81 +		push	dx			; srcseg=0
   13.82 +		push	1			; dst
   13.83 +		push	dx			;    ofs=64k
   13.84 +		push	dx			; dstseg=0
   13.85 +		extrn   _memcpy32:near
   13.86 +		call	_memcpy32
   13.87 +		add	sp,16
   13.88 +
   13.89 +		ifndef  noelks
   13.90 +		push	ss
   13.91 +		pop	ds
   13.92 +		ifndef	NO386
   13.93 +		cmp	[dword 1E6h],'SKLE'
   13.94 +		else
   13.95 +		cmp	[word 1E6h],'LE'
   13.96 +		jne	notelks
   13.97 +		cmp	[word 1E8h],'SK'
   13.98 +		endif
   13.99 +		jne	notelks
  13.100 +		push	100h
  13.101 +		pop	es
  13.102 +		xor	si,si
  13.103 +		xor	di,di
  13.104 +		mov	ch,05h
  13.105 +		rep
  13.106 +		  movsw
  13.107 +		push	es
  13.108 +		pop	ss
  13.109 +		push	120h
  13.110 +		push	0
  13.111 +notelks:
  13.112 +		endif
  13.113 +
  13.114 +nomove:
  13.115 +		push	ss
  13.116 +		pop	ds
  13.117 +		push	ss
  13.118 +		pop	es
  13.119 +		push	ss
  13.120 +		pop	fs
  13.121 +		push	ss
  13.122 +		pop	gs
  13.123 +		assume	nothing
  13.124 +		assume	cs:DGROUP
  13.125 +
  13.126 +doretf:
  13.127 +                retf
  13.128 +
  13.129 +movedend:
  13.130 +        endp    _set_sregs_jump_seg_ofs
  13.131 +
  13.132 +        ends    _TEXT
  13.133 +
  13.134 +        end
  13.135 +
  13.136 +;###### END OF FILE ############################################
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/linld/stuff/src/LINK.CMD	Tue Nov 22 21:19:01 2016 +0100
    14.3 @@ -0,0 +1,1 @@
    14.4 +_beg.obj memcpy32.obj jump.obj vcpi.obj himem.obj crtl.obj memtop.obj xmm.obj a20.obj load.obj linld.obj _end.obj, linld
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/linld/stuff/src/LINKX.CMD	Tue Nov 22 21:19:01 2016 +0100
    15.3 @@ -0,0 +1,1 @@
    15.4 +_beg.obj memcpy32.obj jump.obj vcpi.obj himem.obj crtl.obj crtlx.obj memtop.obj xmm.obj a20.obj load.obj iso9660.obj tazboot.obj _end.obj, tazboot
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/linld/stuff/src/LINLD.CPP	Tue Nov 22 21:19:01 2016 +0100
    16.3 @@ -0,0 +1,113 @@
    16.4 +// This file is distributed under GPL
    16.5 +//
    16.6 +// LINLD main() lives here
    16.7 +
    16.8 +#include "crtl.h"
    16.9 +#include "common.h"
   16.10 +
   16.11 +static struct image_himem image;
   16.12 +static const char msg_cmdline[] = "Error reading cl=@file";
   16.13 +static char* read_cmdline_or_die(const char* fn) {
   16.14 +    image.errmsg = msg_cmdline;
   16.15 +    open_image(fn, &image);
   16.16 +    u16 size=image.size;
   16.17 +    char *cmdline_buf;
   16.18 +    if(size>=PAGE_SIZE ||
   16.19 +       !(cmdline_buf=(char *)malloc(size)) ||
   16.20 +       read(image.fd, cmdline_buf, size) != size)
   16.21 +        die(msg_cmdline);
   16.22 +    // Strip any trailing cr/lf
   16.23 +    char *p=cmdline_buf+size;
   16.24 +    char c='\0';
   16.25 +    do {
   16.26 +        // Replace all other cr/lfs with spaces
   16.27 +        if(*--p>=' ') c=' ';
   16.28 +	else *p = c;
   16.29 +    } while (p>cmdline_buf);
   16.30 +    return cmdline_buf;
   16.31 +}
   16.32 +
   16.33 +const char* kernel_name = "bzImage";
   16.34 +const char* initrd_name;
   16.35 +const char* cmdline = "auto";
   16.36 +u16 root_dev;
   16.37 +u16 vid_mode;           // -3 = ask
   16.38 +                        // -2 = Extended VGA
   16.39 +                        // -1 = Normal VGA
   16.40 +                        //  n = as "n" was pressed
   16.41 +
   16.42 +inline void syntax() {
   16.43 +    die("Syntax:" NL
   16.44 +        "LINLD [image=file] [initrd=files] [vga=mode] [root=num] [mem=max] [cl=cmdline]" NL
   16.45 +        "vga mode: ask,extended,normal or dec/oct/hex number" NL
   16.46 +        "Defaults:" NL
   16.47 +        "\timage=bzImage" NL
   16.48 +        "\tinitrd,vga,root=(void)" NL
   16.49 +        "\tmem=256m" NL
   16.50 +        "\tcl=auto" NL
   16.51 +        "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
   16.52 +        "Use cl=@filename to take cmdline from file"
   16.53 +#if 1
   16.54 +        NL NL "Examples:" NL
   16.55 +        "\tlinld initrd=rootfs4.gz,rootfs3.gz,rootfs2.gz,rootfs1.gz \"cl=rw root=/dev/null video=-32\""
   16.56 +	NL NL "\tlinld image=memtest"
   16.57 +#endif
   16.58 +    );
   16.59 +}
   16.60 +
   16.61 +int main(int argc, char *argv[]) {
   16.62 +    // Believe it or not - this enables A20
   16.63 +    // on my box! Must be DOS in HMA...   -vda
   16.64 +    puts("LINLD v" VERSION_STR "+");
   16.65 +
   16.66 +    // Parse command line
   16.67 +
   16.68 +    if(argc<2) {
   16.69 +dosyntax:
   16.70 +        syntax();
   16.71 +    }
   16.72 +    {for(int i=1;i<argc;i++) {
   16.73 +	char *s=argv[i];
   16.74 +        if(strhead(s,"image=") == 0) {
   16.75 +            kernel_name=s+6;
   16.76 +        }
   16.77 +        else if(strhead(s,"initrd=") == 0) {
   16.78 +            initrd_name = s+7;
   16.79 +        }
   16.80 +        else if(strhead(s,"cl=") == 0) {
   16.81 +            cmdline=s+3;
   16.82 +            if (cmdline[0] == '@') {
   16.83 +                cmdline=read_cmdline_or_die(cmdline+1);
   16.84 +                puts("Kernel command line:");
   16.85 +                puts(cmdline);
   16.86 +            }
   16.87 +        }
   16.88 +        else if(strhead(s,"vga=") == 0) {
   16.89 +	    s+=4;
   16.90 +	    const char c = *s|0x20;
   16.91 +            if (c == 'a') vid_mode = -3;
   16.92 +            else if (c == 'e') vid_mode = -2;
   16.93 +            else if (c == 'n') vid_mode = -1;
   16.94 +            else vid_mode = strtol(s);
   16.95 +        }
   16.96 +        else if(strhead(s,"root=") == 0) {
   16.97 +            root_dev = strtol(s+5);
   16.98 +        }
   16.99 +        else if(strhead(s,"mem=") == 0) {
  16.100 +            topmem = strtol(s+4);
  16.101 +        }
  16.102 +        else if(strhead(s,"-f") == 0) {
  16.103 +            extern int skip_xmmalloc;
  16.104 +            skip_xmmalloc++;
  16.105 +        }
  16.106 +        else
  16.107 +            goto dosyntax;
  16.108 +    }}
  16.109 +
  16.110 +    puts(load_kernel());
  16.111 +    load_initrd();
  16.112 +    boot_kernel();
  16.113 +
  16.114 +    // Let compiler be happy
  16.115 +    return _AX;
  16.116 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/linld/stuff/src/LOAD.CPP	Tue Nov 22 21:19:01 2016 +0100
    17.3 @@ -0,0 +1,384 @@
    17.4 +// This file is distributed under GPL
    17.5 +
    17.6 +#include "crtl.h"
    17.7 +#include "common.h"
    17.8 +
    17.9 +/***************
   17.10 +    Memory layout assumed by kernel boot process
   17.11 +    --------------------------------------------
   17.12 +    Note: claims that kernel setup is relocatable are
   17.13 +    still not 100% valid:
   17.14 +    bzImage decompressing trashes 10000-8ffff range,
   17.15 +    so rm loader -> pm kernel info is lost if it was here...
   17.16 +    So I had to stick to 90000.
   17.17 +
   17.18 +10000000+------------------------+  <- 256m
   17.19 +        |  initrd                |      initrd is at top of mem, but
   17.20 +        |                        |      not higher than 256m
   17.21 +        +------------------------+
   17.22 +        +------------------------+
   17.23 +        |  bzImage               |      bzImage is at 1m
   17.24 +        |                        |      VCPI/XMS/64k offset tricks used...
   17.25 +00100000+------------------------+  <- 1m
   17.26 +        |  video, BIOS etc       |      Do not use.
   17.27 +000A0000+------------------------+
   17.28 +        |  Reserved for BIOS     |      Do not use.  Reserved for BIOS EBDA.
   17.29 +0009A000+------------------------+  <- stack top for kernel rm code
   17.30 +        |  Cmdline               |
   17.31 +00098000+------------------------+  <- heap top for kernel rm code
   17.32 +        |  Kernel setup          |      The kernel real-mode code.
   17.33 +00090200+------------------------+
   17.34 +        |  Kernel boot sector    |      The kernel legacy boot sector.
   17.35 +00090000+------------------------+
   17.36 +        |  Zapped by ungzip      |      Historically zImages were loaded here
   17.37 +        | (zImage once was here) |      bzImages use this space for ungzipping
   17.38 +00010000+------------------------+
   17.39 +        |  Boot loader           |  <- Boot sector entry point 0000:7C00
   17.40 +00001000+------------------------+
   17.41 +        |  Reserved for MBR/BIOS |
   17.42 +00000800+------------------------+
   17.43 +        |  Typically used by MBR |
   17.44 +00000600+------------------------+
   17.45 +        |  BIOS use only         |
   17.46 +00000000+------------------------+
   17.47 +*/
   17.48 +
   17.49 +struct first1k_t {
   17.50 +                            // these two set by rm setup:
   17.51 +    u16     curr_curs;      // 0000 saved cursor position
   17.52 +    u16     ext_mem_size;   // 0002 extended memory size in Kb (from int 0x15 fn 0x88)
   17.53 +    u8      pad00[0x20-4];
   17.54 +                            // old-style cmdline (not used in LINLD (yet?))
   17.55 +    u16     cl_magic;       // 0020 commandline magic number (=0xA33F)
   17.56 +    u16     cl_ofs;         // 0022 commandline offset
   17.57 +    u8      pad10[0x80-0x24];
   17.58 +                            // these two set by rm setup:
   17.59 +    u8      hd0_disk_par[16]; // 0080 hd0-disk-parameter from intvector 0x41
   17.60 +    u8      hd1_disk_par[16]; // 0090 hd1-disk-parameter from intvector 0x46
   17.61 +    u8      pad20[0x01e0-0xa0];
   17.62 +                            // this is set by rm setup:
   17.63 +    u32     alt_mem_size;   // 01E0 extended memory size in Kb (from int 0x15 fn 0xe801)
   17.64 +    u8      pad28[0x01f1-0x1e4];
   17.65 +
   17.66 +    u8      setup_sects;    // 01F1 The size of the setup in sectors
   17.67 +                            //      boot sector is NOT included here
   17.68 +    u16     ro_flag;        // 01F2 If set, the root is mounted readonly
   17.69 +    u16     syssize;        // 01F4 DO NOT USE - for bootsect.S use only:
   17.70 +                            //      size of pm part of kernel
   17.71 +                            //      (in 16 byte units, rounded up)
   17.72 +    u16     swap_dev;       // 01F6 DO NOT USE - obsolete
   17.73 +    u16     ram_size;       // 01F8 DO NOT USE - for bootsect.S use only:
   17.74 +                            //      if nonzero then kernel
   17.75 +                            //      (driver/block/ramdisk.c: rd_load())
   17.76 +                            //      will try to load the contents for the ramdisk
   17.77 +                            //      from the "root_dev" which MUST then have the
   17.78 +                            //      floppyMAJOR
   17.79 +                            //      The file-system on that floppy must be MINIX
   17.80 +                            //      If rd_load() succeeds it sets the root_dev
   17.81 +                            //      to the ramdisk for mounting it
   17.82 +    u16     vid_mode;       // 01FA Video mode control
   17.83 +    u16     root_dev;       // 01FC Default root device number
   17.84 +    u16     boot_flag;      // 01FE 0xAA55 magic number
   17.85 +    u16     jump;           // 0200 Jump instruction
   17.86 +    u32     header;         // 0202 Magic signature "HdrS"
   17.87 +    u16     version;        // 0206 Boot protocol version supported
   17.88 +    u16     realmode_switch_ofs; // 0208 Hook called just before rm->pm
   17.89 +    u16     realmode_switch_seg;
   17.90 +    u16     start_sys_seg;  // 020E
   17.91 +    u16     kernel_version; // 020C Points to kernel version string
   17.92 +    u8      type_of_loader; // 0210 Boot loader identifier
   17.93 +    u8      loadflags;      // 0211 Boot protocol option flags
   17.94 +    u16     setup_move_size;// 0212 Move to high memory size (used with hooks)
   17.95 +    u32     code32_start;   // 0214 Boot loader hook (see below)
   17.96 +    u32     initrd_buf;     // 0218 initrd load address (set by boot loader)
   17.97 +    u32     initrd_size;    // 021C initrd size (set by boot loader)
   17.98 +    u32     bootsect_kludge;// 0220 DO NOT USE - for bootsect.S use only
   17.99 +    u16     heap_end_ptr;   // 0224 Free memory after setup end
  17.100 +    u16     pad1;           // 0226 Unused
  17.101 +    u32     cmd_line_ptr;   // 0228 32-bit pointer to the kernel command line
  17.102 +    u8      pad30[0x400-0x22c]; // 022C
  17.103 +                            // 02D0 up to 32 20-byte mem info structs from
  17.104 +                            // int 0x15 fn 0xe820
  17.105 +}; //__attribute((packed));
  17.106 +
  17.107 +#if sizeof(first1k_t)!=0x400
  17.108 +#error BUG: Bad first1k
  17.109 +#endif
  17.110 +
  17.111 +const u32 HdrS = 'H' + ('d'<<8) + (u32('r')<<16) + (u32('S')<<24);
  17.112 +
  17.113 +u8* rm_buf;
  17.114 +static u16 rm_size;
  17.115 +u8 pm_high;
  17.116 +struct image_himem pm;
  17.117 +struct image_himem initrd;
  17.118 +
  17.119 +static void memcpy_image(struct image_himem *m) {
  17.120 +    if (m->fallback != m->buf)
  17.121 +        memcpy32(
  17.122 +            0, m->fallback, // dst seg,ofs
  17.123 +            0, m->buf,      // src seg,ofs
  17.124 +            m->size         // size
  17.125 +        );
  17.126 +}
  17.127 +
  17.128 +// Called from inside kernel just before rm->pm
  17.129 +// _loadds _saveregs: done by hand
  17.130 +void far last_ditch() {
  17.131 +    cli();  // we start doing *really* destructive things to DOS/BIOS
  17.132 +            // it means: do not even try to enable ints
  17.133 +            // or call BIOS services after this
  17.134 +    asm {
  17.135 +        push    ds
  17.136 +        push    cs
  17.137 +        pop     ds
  17.138 +#ifndef NO386
  17.139 +        pusha
  17.140 +#else
  17.141 +        push	ax
  17.142 +        push	bx
  17.143 +        push	cx
  17.144 +        push	dx
  17.145 +#endif
  17.146 +    }
  17.147 +    if(pm.fallback > _1m) pm.fallback = _1m;
  17.148 +    if(vcpi==0) {
  17.149 +        // Move kernel
  17.150 +        memcpy_image(&pm);
  17.151 +        // Move initrd
  17.152 +        memcpy_image(&initrd);
  17.153 +    } else { //vcpi
  17.154 +        vm2rm();
  17.155 +        // Move kernel
  17.156 +        // 'Gathering' copy in chunks of PAGE_SIZE
  17.157 +        // No risk of overlapping: kernel is copied from above to 1m mark
  17.158 +        pm.size = PAGE_SIZE;
  17.159 +        u32 *p = pm.bufv;
  17.160 +        if (p) while(*p) {
  17.161 +            pm.buf = *p;
  17.162 +            memcpy_image(&pm);
  17.163 +            p++; pm.fallback+=PAGE_SIZE;
  17.164 +        }
  17.165 +        // Move initrd
  17.166 +        if(initrd.fallback) {
  17.167 +            // This is tricky: copy initrd backwards to reduce
  17.168 +            // risk of overlapping: use the fact that initrd is copied
  17.169 +            // to the very top of ram
  17.170 +            // (overlapping still can happen with more than 256mb ram)
  17.171 +            // (generic solution for this overwrite problem, anyone?)
  17.172 +            p=initrd.bufv;
  17.173 +            initrd.size = PAGE_SIZE;
  17.174 +            do {
  17.175 +                p++; initrd.fallback+=PAGE_SIZE;
  17.176 +            } while(*p);
  17.177 +            do {
  17.178 +                p--; initrd.fallback-=PAGE_SIZE;
  17.179 +                initrd.buf = *p;
  17.180 +                memcpy_image(&initrd);
  17.181 +            } while(p != initrd.bufv);
  17.182 +        }
  17.183 +    }
  17.184 +    asm {
  17.185 +#ifndef NO386
  17.186 +        popa
  17.187 +#else
  17.188 +        pop	dx
  17.189 +        pop	cx
  17.190 +        pop	bx
  17.191 +        pop	ax
  17.192 +#endif
  17.193 +        pop     ds
  17.194 +    }
  17.195 +}
  17.196 +
  17.197 +// register value to launch the kernel real mode code
  17.198 +#ifdef NO386
  17.199 +static u32 sssp;
  17.200 +static u32 csip;
  17.201 +extern "C" u16 topseg();
  17.202 +#else
  17.203 +const  u32 sssp=0x9000A000;
  17.204 +static u32 csip=0x90200000;
  17.205 +#define topseg() 0x9000
  17.206 +#endif
  17.207 +
  17.208 +static const char kernel_file_error[] = "Can't use kernel file";
  17.209 +char* load_kernel() {
  17.210 +
  17.211 +#ifdef NO386
  17.212 +    sssp=((u32)topseg()<<16)+0xA000;
  17.213 +    csip=((u32)(topseg()+0x20)<<16);
  17.214 +#endif
  17.215 +    // Open kernel, read first kb, check it
  17.216 +    pm.errmsg = kernel_file_error;
  17.217 +    open_image(kernel_name, &pm);
  17.218 +
  17.219 +    char *version_string;
  17.220 +  {
  17.221 +    struct first1k_t *first1k;
  17.222 +    first1k = (first1k_t*) (rm_buf = malloc_or_die(_32k));
  17.223 +   {
  17.224 +    u16 rm_seek;
  17.225 +
  17.226 +    // Do not use malloc below until heap_top adjustment (see <*>)
  17.227 +    if (read(pm.fd, rm_buf, rm_seek=0x400) != 0x400) {
  17.228 +  readfail:
  17.229 +        die(kernel_file_error);
  17.230 +    }
  17.231 +
  17.232 +    if(!first1k->setup_sects) {
  17.233 +#if 1
  17.234 +        if(* (int *) &first1k->pad10[0x3F-0x24] == 0x3AE8) {
  17.235 +            lseek(pm.fd,rm_seek=0x200,SEEK_SET);
  17.236 +            csip=((u32)topseg()<<16)+0x0042;
  17.237 +        }
  17.238 +        else
  17.239 +#endif
  17.240 +        first1k->setup_sects=4;
  17.241 +    }
  17.242 +    rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
  17.243 +    if(rm_size>_32k || first1k->boot_flag != 0xAA55)
  17.244 +        die("It's not a kernel");
  17.245 +    heap_top = rm_buf+rm_size;  // <*>
  17.246 +
  17.247 +    // Read remaining rm loader
  17.248 +
  17.249 +    {
  17.250 +    u16 cnt = rm_size-rm_seek;
  17.251 +    if (read(pm.fd, rm_buf+rm_seek, cnt) != cnt) goto readfail;
  17.252 +    }
  17.253 +   }
  17.254 +
  17.255 +    // Tell rm loader some info
  17.256 +
  17.257 +    if(vid_mode) first1k->vid_mode = vid_mode;
  17.258 +    if(root_dev) first1k->root_dev = root_dev;
  17.259 +    version_string = 0;
  17.260 +
  17.261 +#if 1
  17.262 +    if(first1k->header == HdrS) { // starting linux 1.3.73
  17.263 +	if(first1k->loadflags & 1) {
  17.264 +#else
  17.265 +    if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
  17.266 +        die("I can't load bzImage low");
  17.267 +    {
  17.268 +        {
  17.269 +#endif
  17.270 +            pm_high++;
  17.271 +
  17.272 +            // Hook on int15 to work around fn 88 DOS breakage
  17.273 +            hook_int15_88();
  17.274 +
  17.275 +            // * will be called just before rm -> pm
  17.276 +            first1k->realmode_switch_ofs = ofs(last_ditch);
  17.277 +            first1k->realmode_switch_seg = seg(last_ditch);
  17.278 +        }
  17.279 +        if(first1k->kernel_version)
  17.280 +            version_string = (char *) first1k+first1k->kernel_version+0x200;
  17.281 +        first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
  17.282 +        if(first1k->version >= 0x201) {
  17.283 +            // * offset limit of the setup heap
  17.284 +            //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
  17.285 +            first1k->heap_end_ptr = _32k-0x0200;
  17.286 +            first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
  17.287 +        }
  17.288 +        // * if we will ever stop moving ourself to 0x90000
  17.289 +        //   we must say setup.S how much to move
  17.290 +        //first1k->setup_move_size = _32k;
  17.291 +        if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
  17.292 +            first1k->cmd_line_ptr = (((u32)(topseg()+0x0800))<<4);
  17.293 +            goto cmd_line_ok;
  17.294 +        }
  17.295 +    }
  17.296 +    first1k->cl_magic = 0xA33F;
  17.297 +    first1k->cl_ofs   = 0x8000;
  17.298 +  }
  17.299 +
  17.300 +cmd_line_ok:
  17.301 +    // Check and enable A20 if needed
  17.302 +    enable_a20_or_die();
  17.303 +
  17.304 +    // Read remaining kernel (pm part)
  17.305 +    // Try to load kernel high, maybe even blindly storing it
  17.306 +    // in unallocated memory as a last resort
  17.307 +
  17.308 +    pm.fallback = (u32((u16(_CS)+0x1FFF)&0xF000)<<4);
  17.309 +    pm.size -= rm_size;
  17.310 +    if(pm.fallback+pm.size > (((u32)topseg())<<4) || pm_high) {
  17.311 +        pm.fallback = _1m+_64k;
  17.312 +    }
  17.313 +
  17.314 +    load_image(&pm);
  17.315 +    return version_string;
  17.316 +}
  17.317 +
  17.318 +// Read initrd if needed
  17.319 +
  17.320 +static const char msg_initrd[] = "Can't use initrd file";
  17.321 +void load_initrd() {
  17.322 +    struct image_himem *m = &initrd;
  17.323 +    if (!initrd_name && !initrd.fd) return;
  17.324 +    if (!pm.fd) {
  17.325 +noinitrd:
  17.326 +        puts(msg_initrd);
  17.327 +        return;
  17.328 +    }
  17.329 +    m->errmsg = msg_initrd;
  17.330 +    open_image(initrd_name, m);
  17.331 +
  17.332 +    m->fallback = (memtop()-m->size) & (~PAGE_MASK);
  17.333 +    if (m->fallback < pm.fallback + pm.size) {
  17.334 +        close(m->fd);
  17.335 +	goto noinitrd;
  17.336 +    }
  17.337 +
  17.338 +    load_image(m);
  17.339 +    struct first1k_t *first1k = (first1k_t*)rm_buf;
  17.340 +    if(first1k->header == HdrS) {
  17.341 +        first1k->initrd_buf  = m->fallback;
  17.342 +        first1k->initrd_size = m->size;
  17.343 +    }
  17.344 +}
  17.345 +
  17.346 +void boot_kernel() {
  17.347 +
  17.348 +    // Shrink stack: we won't need much of it now and have no malloc() plans
  17.349 +    {
  17.350 +        u16 new_SP=u16(heap_top)+0x100;
  17.351 +        if(_SP>new_SP) _SP=new_SP;
  17.352 +    }
  17.353 +    if( u16(_CS)+(u16(_SP)>>4) >= topseg() ) {
  17.354 +        // Oops! We can stomp on our toes... better stop now
  17.355 +        die("Loaded too close to 9000:0");
  17.356 +    }
  17.357 +
  17.358 +    cli(); // we start doing destructive things to DOS
  17.359 +
  17.360 +    // Move rm loader & commandline to 0x90000
  17.361 +    if(vcpi==0) {
  17.362 +        memcpy32(
  17.363 +            topseg(),0,
  17.364 +            seg(rm_buf),ofs(rm_buf),
  17.365 +            rm_size //_32k
  17.366 +        );
  17.367 +        memcpy32(
  17.368 +            topseg()+0x0800,0,
  17.369 +            seg(cmdline),ofs(cmdline),
  17.370 +            PAGE_SIZE
  17.371 +        );
  17.372 +    } else { //vcpi
  17.373 +        u32 dst=((u32)topseg()<<4);
  17.374 +        u16 pos=ofs(rm_buf);
  17.375 +        do {
  17.376 +            memcpy_vcpi(dst,seg(rm_buf),pos);
  17.377 +            dst+=PAGE_SIZE;
  17.378 +            pos+=PAGE_SIZE;
  17.379 +            rm_size-=PAGE_SIZE;
  17.380 +          } while(s16(rm_size) > 0);
  17.381 +        // overkill: copy PAGE_SIZE bytes
  17.382 +        memcpy_vcpi(((u32)(topseg()+0x0800)<<4),seg(cmdline),ofs(cmdline));
  17.383 +    }
  17.384 +
  17.385 +    // Jump to kernel rm code
  17.386 +    set_sregs_jump_seg_ofs(csip, sssp);
  17.387 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/linld/stuff/src/MEMCPY32.ASM	Tue Nov 22 21:19:01 2016 +0100
    18.3 @@ -0,0 +1,351 @@
    18.4 +;***************************************************************
    18.5 +;****** This file is distributed under GPL
    18.6 +;***************************************************************
    18.7 +                ideal
    18.8 +                %crefref
    18.9 +                %noincl
   18.10 +                %nomacs
   18.11 +                p386
   18.12 +
   18.13 +        group   DGROUP  _TEXT,_DATA
   18.14 +        assume  cs:DGROUP,ds:DGROUP
   18.15 +
   18.16 +        segment _DATA byte public use16 'DATA'
   18.17 +msg_badcpu      db      "I need 386+ CPU in real mode or under VCPI manager",0
   18.18 +        ends    _DATA
   18.19 +
   18.20 +        segment _TEXT byte public use16 'CODE'
   18.21 +
   18.22 +;***************************************************************
   18.23 +;int _is_vm86();
   18.24 +;****** Return: AX=1 - it is a 386+ in virtual86 mode with vcpi
   18.25 +;******         AX=0 - it is a 386+ in real mode
   18.26 +;******         otherwise abort program
   18.27 +;****** Uses:   Flags
   18.28 +;***************************************************************
   18.29 +        global  _is_vm86:near
   18.30 +        proc    _is_vm86 near
   18.31 +
   18.32 +; Check for oldies
   18.33 +		mov	ax, 0F000h
   18.34 +		pushf
   18.35 +		push	ax		; < 286 : flags[12..15] are forced 1
   18.36 +		popf			; = 286 : flags[12..15] are forced 0
   18.37 +		pushf			; > 286 : only flags[15] is forced 0
   18.38 +		pop	dx
   18.39 +		popf
   18.40 +		add	dh,ah		; NS=386+, NC=286
   18.41 +		ifndef	NO386
   18.42 +                js	@@no_vcpi   	;it is a 86/186/286, not a 386+
   18.43 +		else
   18.44 +		js	@@ret
   18.45 +		endif
   18.46 +; Check for vm
   18.47 +                smsw    ax      ;SMSW cannot be trapped! :-)
   18.48 +                and     ax,1	;MSW_PE
   18.49 +; We're in vm
   18.50 +                jnz     check_vcpi
   18.51 +
   18.52 +; It's a 386 in real mode, chk for paging (crazy but possible)
   18.53 +                mov     edx,cr0
   18.54 +                shl     edx,1   ;CR0_PG to CF
   18.55 +		jc	@@no_vcpi
   18.56 +@@ret:
   18.57 +                ret
   18.58 +
   18.59 +;***************************************************************
   18.60 +;****** Helper: checks for vcpi
   18.61 +;***************************************************************
   18.62 +label   check_vcpi near
   18.63 +                push    ds
   18.64 +; Check whether it is safe to call 67h (we trust only known EMM managers)
   18.65 +                push    0
   18.66 +                pop     ds
   18.67 +                mov     ds,[word 67h*4+2]
   18.68 +                cmp     [dword 10+4],'0XXX'
   18.69 +                jne     @@skip
   18.70 +                mov     eax,[dword 10]
   18.71 +                cmp     eax,'XMME'
   18.72 +                je      @@skip
   18.73 +        ; this also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
   18.74 +                cmp     eax,'QMME'
   18.75 +@@skip:
   18.76 +                pop     ds
   18.77 +                jne     @@no_vcpi
   18.78 +; Check emm manager status and version
   18.79 +                mov     ah,40h          ; get status
   18.80 +                int     67h
   18.81 +                test    ah,ah
   18.82 +                jnz     @@no_vcpi
   18.83 +                mov     ah,46h          ; get version
   18.84 +                int     67h
   18.85 +                test    ah,ah
   18.86 +                jnz     @@no_vcpi
   18.87 +                cmp     al,40h          ; version must be >= 4.0
   18.88 +                jb      @@no_vcpi
   18.89 +; Check vcpi manager status
   18.90 +              ;;mov     ax,5A01h        ; ALLOCATE RAW PAGES
   18.91 +              ;;mov     bx,4
   18.92 +              ;;int     67h
   18.93 +              ;;test    ah,ah
   18.94 +              ;;jnz     @@no_vcpi
   18.95 +              ;;push    dx              ;$ save handle
   18.96 +                mov     ax,0DE00h       ; check for vcpi present
   18.97 +                int     67h
   18.98 +                mov     al,1
   18.99 +                test    ah,ah
  18.100 +                jz      @@386vcpi
  18.101 +              ;;pop     dx              ;$ handle
  18.102 +              ;;mov     ax,4500h        ; DEALLOCATE PAGES
  18.103 +              ;;int     67h
  18.104 +@@no_vcpi:
  18.105 +		mov	bx,offset msg_badcpu
  18.106 +                extrn   die:near
  18.107 +		jmp	near die
  18.108 +@@386vcpi:
  18.109 +		mov	[_vcpi],al
  18.110 +                extrn	@init_vcpi$qv:near
  18.111 +                jmp	near @init_vcpi$qv
  18.112 +
  18.113 +        endp    _is_vm86
  18.114 +
  18.115 +
  18.116 +;***************************************************************
  18.117 +;void dos_shutdown()
  18.118 +;***************************************************************
  18.119 +        global  dos_shutdown:near
  18.120 +        proc    dos_shutdown near
  18.121 +
  18.122 +;TODO NO386
  18.123 +dos_shutdown:
  18.124 +		pusha
  18.125 +		xor	bx,bx
  18.126 +		mov	ds,bx
  18.127 +		push	[dword bx+4]		; save step
  18.128 +		mov	ax,sp
  18.129 +		push	ss
  18.130 +		push	ax
  18.131 +		pop	[dword cs:sssp]
  18.132 +		;cmp	[byte bx+7],0F0h
  18.133 +		;jnc	notdos
  18.134 +		mov	[word bx+4],offset step19
  18.135 +		mov	[bx+6],cs
  18.136 +		pushf
  18.137 +		pop	ax
  18.138 +		inc	ah			; set TF
  18.139 +		push	ax
  18.140 +		popf
  18.141 +		jmp	small [dword bx+4*19h]
  18.142 +doiret:
  18.143 +		iret
  18.144 +sssp:
  18.145 +		dd	0
  18.146 +step19:
  18.147 +		push	bx
  18.148 +		push	ds
  18.149 +		mov	bx,sp
  18.150 +		lds	bx,[dword ss:bx+4]	; read cs:ip
  18.151 +		cmp	[word bx],19CDh		; int 19h ?
  18.152 +		pop	ds
  18.153 +		pop	bx
  18.154 +		jne	doiret
  18.155 +notdos:
  18.156 +		lss	sp,[dword cs:sssp]
  18.157 +		xor	bx,bx
  18.158 +		mov	ds,bx
  18.159 +		pop	[dword bx+4]		; restore step
  18.160 +		popa
  18.161 +		push	cs
  18.162 +		pop	ds
  18.163 +		ret
  18.164 +
  18.165 +        endp    dos_shutdown
  18.166 +
  18.167 +
  18.168 +;***************************************************************
  18.169 +;void memcpy32(u16 dstseg,u32 dstofs,u16 srcseg,u32 srcofs,u32 size);
  18.170 +;***************************************************************
  18.171 +;****** Uses:   Flags
  18.172 +;***************************************************************
  18.173 +        global  _memcpy32:near
  18.174 +        proc    _memcpy32 near
  18.175 +
  18.176 +;TODO NO386
  18.177 +; rm32,imm16 helper
  18.178 +macro   addzx_e rm,i
  18.179 +        db      66h
  18.180 +        add     rm,i
  18.181 +        dw      0
  18.182 +endm
  18.183 +                arg     dstseg  :word,  \
  18.184 +                        dstofs  :dword, \
  18.185 +                        srcseg  :word,  \
  18.186 +                        srcofs  :dword, \
  18.187 +                        sz      :dword  = PARAM_SIZE
  18.188 +
  18.189 +                local   GDTR    :pword, \
  18.190 +                        oldGDTR :pword  = TEMP_SIZE
  18.191 +
  18.192 +;****** Init ***************************************************
  18.193 +                enter   TEMP_SIZE,0
  18.194 +                pushf
  18.195 +                push    es ds esi edi
  18.196 +                movzx   esi,[srcseg]
  18.197 +                shl     esi,4
  18.198 +                add     esi,[srcofs]
  18.199 +                movzx   edi,[dstseg]
  18.200 +                shl     edi,4
  18.201 +                add     edi,[dstofs]
  18.202 +	ifndef	pm_only
  18.203 +		mov	eax,00100000h
  18.204 +		cmp	esi,eax
  18.205 +                jnb     pmcopy
  18.206 +		cmp	edi,eax
  18.207 +                jnb     pmcopy
  18.208 +		mov	eax,esi
  18.209 +		shr	eax,4
  18.210 +		mov	ds,ax
  18.211 +		mov	edx,edi
  18.212 +		shr	edx,4
  18.213 +@@movlp:
  18.214 +		mov	ds,ax
  18.215 +		mov	es,dx
  18.216 +		and	si,0Fh
  18.217 +		and	di,0Fh
  18.218 +		mov	cx,08h
  18.219 +		cld
  18.220 +            rep movsw
  18.221 +		inc	ax
  18.222 +		inc	dx
  18.223 +                sub     [sz],10h
  18.224 +                ja	@@movlp
  18.225 +		jmp	done
  18.226 +	endif
  18.227 +pmcopy:
  18.228 +                mov     ecx,[sz]
  18.229 +		mov	dx,-1
  18.230 +
  18.231 +	ifdef	keep_int15
  18.232 +                jecxz   godone
  18.233 +		test	[_vcpi],dl
  18.234 +		jne	with_movsw
  18.235 +
  18.236 +		push	ss
  18.237 +		pop	es
  18.238 +		inc	ecx
  18.239 +		shr	ecx,1
  18.240 +		mov	bx,9318h
  18.241 +clear:
  18.242 +		push	0
  18.243 +		dec	bl
  18.244 +		jnz	clear
  18.245 +  		xchg	eax,esi
  18.246 +  		mov	si,sp
  18.247 +		mov	[si+12h],eax
  18.248 +		mov	[si+1Ah],edi
  18.249 +		mov	[si+10h],dx
  18.250 +		mov	[si+18h],dx
  18.251 +		mov	edi,ecx
  18.252 +		mov	dh,93h
  18.253 +		xchg	bx,[si+14h]
  18.254 +		xchg	dx,[si+1Ch]
  18.255 +mvlp:
  18.256 +		mov	[si+14h],bl
  18.257 +		mov	[si+17h],bh
  18.258 +		mov	[si+1Ch],dl
  18.259 +		mov	[si+1Fh],dh
  18.260 +		xor	ecx,ecx
  18.261 +		mov	ch,80h
  18.262 +		sub	edi,ecx
  18.263 +		pushf
  18.264 +		jnc	domv
  18.265 +		add	ecx,edi
  18.266 +domv:
  18.267 +	;push	bx dx si edi
  18.268 +		mov	ah,87h
  18.269 +		int	15h
  18.270 +	;pop	edi si dx bx
  18.271 +		inc	bx
  18.272 +		inc	dx
  18.273 +		popf
  18.274 +		jnc	mvlp
  18.275 +		add	sp,30h
  18.276 +godone:
  18.277 +		jmp	done
  18.278 +	else
  18.279 +                jecxz   done
  18.280 +	endif
  18.281 +
  18.282 +with_movsw:
  18.283 +                cld
  18.284 +                cmp     esi,edi
  18.285 +                jae     @@do_copy
  18.286 +                add     esi,ecx         ;src<dst: we must do
  18.287 +                dec     esi             ;  copy backwards to avoid
  18.288 +                add     edi,ecx         ;  overwrite bug
  18.289 +                dec     edi             ;
  18.290 +                std                     ;
  18.291 +@@do_copy:
  18.292 +                cli
  18.293 +                sgdt    [oldGDTR]
  18.294 +
  18.295 +;****** Load gdtr **********************************************
  18.296 +                mov     eax,cs
  18.297 +                shl     eax,4
  18.298 +                addzx_e ax,<offset GDT>
  18.299 +                mov     [word GDTR],dx          ;GDT limit = 0FFFFh
  18.300 +                mov     [dword GDTR+2],eax      ;GDT base
  18.301 +                lgdt    [GDTR]
  18.302 +
  18.303 +;****** Go into pm *********************************************
  18.304 +                mov     eax,cr0
  18.305 +                or      al,01h          ;CR0_PE on
  18.306 +                mov     cr0,eax
  18.307 +                jmp     short $+2       ;*Required*!
  18.308 +                                        ;3+ NOPs also work fine (chkd on 386)
  18.309 +;****** Move data **********************************************
  18.310 +                push    0008h
  18.311 +                pop     ds              ;base=0, lim = 4gb
  18.312 +                push    ds              ;
  18.313 +                pop     es              ;
  18.314 +                db      66h     ;operand width override for ecx
  18.315 +                db      67h     ;address width override for esi/edi
  18.316 +            rep movsb
  18.317 +                cld
  18.318 +
  18.319 +;****** Return to rm *******************************************
  18.320 +                dec     ax              ;CR0_PE off
  18.321 +                mov     cr0,eax         ;ds/es limits are *not* reset to 64kb
  18.322 +                                        ;  but who cares :-)
  18.323 +                jmp     short $+2
  18.324 +
  18.325 +;****** Return *************************************************
  18.326 +                lgdt    [oldGDTR]
  18.327 +done:
  18.328 +                cld
  18.329 +                pop     edi esi ds es
  18.330 +                popf
  18.331 +                leave
  18.332 +                ret
  18.333 +
  18.334 +;****** Const data *********************************************
  18.335 +                org     $-8     ;save 8 bytes - they are unused anyway
  18.336 +;0000: unused
  18.337 +GDT             dd      ?,?
  18.338 +;0008: Data seg [0,FFFFFFFF]
  18.339 +                ;       lim_lo              base_lo
  18.340 +                dw      1111111111111111b,  0000000000000000b
  18.341 +                db      00000000b,10010010b,10001111b,00000000b
  18.342 +                ;       base_med  P  S D A  G ??l_hi  base_hi
  18.343 +                ;                  Pl E W    D
  18.344 +
  18.345 +        global  _vcpi:byte
  18.346 +_vcpi		db	0
  18.347 +
  18.348 +        endp    _memcpy32
  18.349 +
  18.350 +        ends    _TEXT
  18.351 +
  18.352 +        end
  18.353 +
  18.354 +;###### END OF FILE ############################################
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/linld/stuff/src/MEMTOP.ASM	Tue Nov 22 21:19:01 2016 +0100
    19.3 @@ -0,0 +1,213 @@
    19.4 +;***************************************************************
    19.5 +;****** This file is distributed under GPL
    19.6 +;***************************************************************
    19.7 +                ideal
    19.8 +                %crefref
    19.9 +                %noincl
   19.10 +                %nomacs
   19.11 +                p386
   19.12 +
   19.13 +        group   DGROUP  _TEXT,_DATA,_BSS
   19.14 +        assume  cs:DGROUP,ds:DGROUP
   19.15 +
   19.16 +
   19.17 +        segment _DATA byte public use16 'DATA'
   19.18 +
   19.19 +        global  _topmem:dword
   19.20 +
   19.21 +_topmem		dd	10000000h	; max 256m
   19.22 +
   19.23 +        ends    _DATA
   19.24 +
   19.25 +        segment _BSS byte public use16 'BSS'
   19.26 +
   19.27 +saved15		dd	?
   19.28 +
   19.29 +        ends    _BSS
   19.30 +
   19.31 +
   19.32 +        segment _TEXT byte public use16 'CODE'
   19.33 +
   19.34 +;***************************************************************
   19.35 +;u32 memtopz();
   19.36 +;***************************************************************
   19.37 +        global  _memtopz:near
   19.38 +        proc    _memtopz near
   19.39 +;***************************************************************
   19.40 +;u32 memtop_e801()
   19.41 +;***************************************************************
   19.42 +;        proc    _memtop_e801 near
   19.43 +
   19.44 +                push    cx bx
   19.45 +                xor     cx,cx           ;fix to work around buggy
   19.46 +                xor     dx,dx           ;  BIOSes which dont clear/set
   19.47 +                stc                     ;  carry on pass/error of
   19.48 +                mov     ax,0E801h
   19.49 +                int     15h
   19.50 +                jc      @@err
   19.51 +                test    cx,cx           ;kludge to handle BIOSes
   19.52 +                jnz     @@use_cxdx      ;  which report their extended
   19.53 +                test    dx,dx           ;  memory in AX/BX rather than
   19.54 +                jnz     @@use_cxdx      ;  CX/DX.  The spec I have read
   19.55 +@@use_axbx:     mov     dx,bx           ;  seems to indicate AX/BX
   19.56 +                jmp     @@end_kludge    ;  are more reasonable anyway...
   19.57 +@@use_cxdx:     xchg    ax,cx
   19.58 +@@end_kludge:                   ;now: dx=64k units above 16m
   19.59 +                                ;     ax=1k units above 1m below 16m (max 3c00h)
   19.60 +                pop     bx cx
   19.61 +                test    dx,dx
   19.62 +                jz      tokb            ;dx=0 here, ax=kbs above 1m
   19.63 +                xor     ax,ax           ;ignore info on low 16M (assume full)
   19.64 +               ;add     dx,100h         ;account for low 16M
   19.65 +                inc     dh              ;account for low 16M (optimized)
   19.66 +                ret
   19.67 +@@err:
   19.68 +;                xor     ax,ax
   19.69 +;                cwd
   19.70 +;                ret
   19.71 +;        endp    _memtop_e801
   19.72 +
   19.73 +
   19.74 +;***************************************************************
   19.75 +;u32 memtop_88()
   19.76 +;***************************************************************
   19.77 +;        proc    _memtop_88 near
   19.78 +
   19.79 +                mov     ah,88h
   19.80 +                int     15h             ;ax=kbs above 1m
   19.81 +                jnc     @@ok            ;  error: cf=1 or ax=0
   19.82 +                xor     ax,ax           ;
   19.83 +@@ok:
   19.84 +                xor     dx,dx
   19.85 +                test    ax,ax           ;happens on big mem systems
   19.86 +                jz      @@fail
   19.87 +tokb:
   19.88 +                add     ah,4h           ;account for 1024 low kb
   19.89 +                adc     dx,dx           ;  (optimized to death)
   19.90 +		ifndef	NO386
   19.91 +                shld    dx,ax,10        ;multiply by 1024
   19.92 +                shl     ax,10           ;  (kbytes -> bytes)
   19.93 +		else
   19.94 +@@lp:
   19.95 +		mov	cx,10
   19.96 +                shl     ax,1            ;multiply by 1024
   19.97 +		rcl	dx,1
   19.98 +		loop	@@lp
   19.99 +		endif
  19.100 +;		mov	cx,ax
  19.101 +;		or	cx,dx		;update ZF
  19.102 +;@@fail:
  19.103 +                ret
  19.104 +;        endp    _memtop_88
  19.105 +
  19.106 +@@fail:
  19.107 +
  19.108 +;        proc    _memtopz near
  19.109 +
  19.110 +;                call	_memtop_e801
  19.111 +;		jnz	@@ok
  19.112 +;                call	_memtop_88
  19.113 +;		jnz	@@ok
  19.114 +
  19.115 +;***************************************************************
  19.116 +;u32 memtop_cmos()
  19.117 +;***************************************************************
  19.118 +
  19.119 +                pushf
  19.120 +                cli
  19.121 +                call	rdcmos17
  19.122 +                popf
  19.123 +		xor     dx,dx
  19.124 +		jmp	tokb
  19.125 +
  19.126 +rdcmos17:       mov     al,18h		; read bytes 17-18 from CMOS
  19.127 +                call    @@rdcmos
  19.128 +                mov     ah,al
  19.129 +                mov     al,17h
  19.130 +@@rdcmos:       out     70h,al
  19.131 +                call    @@ret
  19.132 +                in      al,71h
  19.133 +@@ret:
  19.134 +                ret
  19.135 +
  19.136 +
  19.137 +;***************************************************************
  19.138 +;u32 memtop();
  19.139 +;***************************************************************
  19.140 +        global  _memtop:near
  19.141 +_memtop:
  19.142 +		call	_memtopz
  19.143 +		mov	cx,40h		; min 4m
  19.144 +; If reported mem is ridiculously low, presume
  19.145 +; we had trouble detecting memory size
  19.146 +		cmp	dx,cx
  19.147 +		jb	@@set
  19.148 +		mov	cx,[word _topmem+2]	; max 256m ?
  19.149 +; Kernel can have trouble with initrd at very high addr:
  19.150 +; limit mem top to 256m
  19.151 +		cmp	dh,ch
  19.152 +		jb	@@done
  19.153 +@@set:
  19.154 +		xchg	ax,cx
  19.155 +		cwd
  19.156 +		xchg	ax,dx
  19.157 +@@done:
  19.158 +; Round down to page boundary.
  19.159 +; Or else initrd's tail may end up in last, partial page.
  19.160 +; Kernel will refuse to use such initrd.
  19.161 +		and	ax,0f000h
  19.162 +;@@ok:
  19.163 +		ret
  19.164 +
  19.165 +        endp    _memtopz
  19.166 +
  19.167 +;***************************************************************
  19.168 +;void hook_int15_88();
  19.169 +;***************************************************************
  19.170 +        global  _hook_int15_88:near
  19.171 +        proc    _hook_int15_88 near
  19.172 +
  19.173 +		ifndef  xmm_hook
  19.174 +                mov     ax,4300h
  19.175 +                int     2fh
  19.176 +                cmp     al,80h
  19.177 +                je      @@skip
  19.178 +		endif
  19.179 +		push	0
  19.180 +		pop	es
  19.181 +		mov	bx,15*4
  19.182 +		ifndef	NO386
  19.183 +		mov	eax,[bx]
  19.184 +		mov	[saved15],eax
  19.185 +		else
  19.186 +		mov	ax,[bx]
  19.187 +		mov	[word saved15],ax
  19.188 +		mov	ax,[bx+2]
  19.189 +		mov	[word saved15+2],ax
  19.190 +		endif
  19.191 +		mov	[word bx],offset int15_88
  19.192 +		mov	[bx+2],cs
  19.193 +@@skip:
  19.194 +		ret
  19.195 +int15_88:
  19.196 +                cmp     ah,88h
  19.197 +                je      @@do88
  19.198 +                jmp     [saved15]
  19.199 +@@do88:
  19.200 +                pushf
  19.201 +                call    [saved15]
  19.202 +                test    ax,ax
  19.203 +                jnz     @@iret
  19.204 +
  19.205 +;****** Read extended mem size (CMOS bytes 17h,18h (lo,hi))
  19.206 +                call	rdcmos17
  19.207 +@@iret:
  19.208 +                iret
  19.209 +
  19.210 +        endp    _hook_int15_88
  19.211 +
  19.212 +        ends    _TEXT
  19.213 +
  19.214 +        end
  19.215 +
  19.216 +;###### END OF FILE ############################################
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/linld/stuff/src/TAZBOOT.CPP	Tue Nov 22 21:19:01 2016 +0100
    20.3 @@ -0,0 +1,228 @@
    20.4 +// This file is distributed under GPL
    20.5 +//
    20.6 +// TAZBOOT main() lives here
    20.7 +
    20.8 +#include "crtl.h"
    20.9 +#include "crtlx.h"
   20.10 +#include "common.h"
   20.11 +#include "iso9660.h"
   20.12 +
   20.13 +static void usage()
   20.14 +{
   20.15 +	puts("Usage: tazboot [[@commands]|[kernel=<bzimage>] \
   20.16 +[initrd=<rootfs>[,<rootfs2>...]] [bootfrom=<isofile>] ...]\r\n\n\
   20.17 +Defaults: tazboot kernel=bzImage auto\r\n\n\
   20.18 +Examples for tazboot.cmd:\r\n\n\
   20.19 +  bootfrom=\\isos\\slitaz-4.0.iso\r\n\
   20.20 +  kernel=boot/bzImage\r\n\
   20.21 +  initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz,\\slitaz\\extrafs.gz\r\n\
   20.22 +  rw root=/dev/null vga=normal autologin\r\n\n\
   20.23 +  kernel=\\slitaz\\elks\r\n\
   20.24 +  root=/dev/bda1 ro\r\n");
   20.25 +	exit(1);
   20.26 +}
   20.27 +
   20.28 +#define MAXINITRD 10
   20.29 +static struct initrd_state {
   20.30 +	u32 ofs[MAXINITRD];
   20.31 +	u32 size[MAXINITRD];
   20.32 +	u16 cnt;
   20.33 +} initrd_state;
   20.34 +
   20.35 +static void next_chunk(struct image_himem *m)
   20.36 +{
   20.37 +	m->chunk_size = 0;
   20.38 +	if (m->state >= initrd_state.cnt) return;
   20.39 +	lseek(m->fd,initrd_state.ofs[m->state],SEEK_SET);
   20.40 +	m->chunk_size = initrd_state.size[m->state];
   20.41 +	m->state++;
   20.42 +}
   20.43 +
   20.44 +static void addinitrd()
   20.45 +{
   20.46 +	if (initrd_state.cnt >= MAXINITRD) return;
   20.47 +	initrd_state.size[initrd_state.cnt] = isofilesize;
   20.48 +	initrd_state.ofs[initrd_state.cnt] = isofileofs;
   20.49 +	initrd_state.cnt++;
   20.50 +	initrd.size += (isofilesize+3)&-4;
   20.51 +}
   20.52 +
   20.53 +static void load_initrds()
   20.54 +{
   20.55 +	if (!initrd.size) return;
   20.56 +	initrd.next_chunk = next_chunk;
   20.57 +	initrd.fd = isofd;
   20.58 +	initrd.state = 0;
   20.59 +	next_chunk(&initrd);
   20.60 +	load_initrd();
   20.61 +}
   20.62 +
   20.63 +static void pm_next_chunk(struct image_himem *m)
   20.64 +{
   20.65 +	if (!m->state++) m->chunk_size = m->size;
   20.66 +}
   20.67 +
   20.68 +static void isokernel()
   20.69 +{
   20.70 +	pm.size = (isofilesize+3)&-4;
   20.71 +	pm.fd = isofd;
   20.72 +	pm.next_chunk = pm_next_chunk;
   20.73 +}
   20.74 +
   20.75 +char _cmdline[256];
   20.76 +const char *cmdline = (const char *) _cmdline;
   20.77 +extern int skip_xmmalloc;
   20.78 +static void bootiso(char **iso)
   20.79 +{
   20.80 +	char *init = " rdinit=/init.exe", *mode="menu";
   20.81 +	char *s, c, rootfs[16], fallback[16];
   20.82 +	int restart, isknoppix = 0;
   20.83 +	unsigned long magic;
   20.84 +	
   20.85 +	if (!*iso || isoreset(*iso) < 0) return;
   20.86 +	skip_xmmalloc++;
   20.87 +	isoopen("boot") >= 0 ||
   20.88 +	isoopen("live") >= 0 ||	// debian
   20.89 +	isoopen("casper") >= 0;	// ubuntu
   20.90 +	if (iso[1] && !strcmp(mode = iso[1], "text"))
   20.91 +		init = "";
   20.92 +	do {
   20.93 +		if (isoopen(mode) >= 0		||	// custom
   20.94 +		    isoopen("bzImage") >= 0	|| 	// SliTaz
   20.95 +		    isoopen("vmlinuz") >= 0	||	// misc
   20.96 +		    (isoopen("linux") >= 0 && ++isknoppix)) {
   20.97 +			isokernel();
   20.98 +			magic = kver2ul(load_kernel());
   20.99 +			break;
  20.100 +		}
  20.101 +	} while (isoopen("isolinux") >= 0);		// Knoppix
  20.102 +	fallback[0] = 0;
  20.103 +	for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
  20.104 +		if (strstr(isofilename, ".gz"))
  20.105 +			strcpy(fallback, isofilename);
  20.106 +		if (strhead(isofilename, "rootfs") 
  20.107 +			|| c > isofilename[6]) continue;
  20.108 +		strcpy(rootfs, isofilename);
  20.109 +		c = isofilename[6];
  20.110 +	}
  20.111 +
  20.112 +	strcpy(_cmdline,"rw root=/dev/null autologin bootfrom=");
  20.113 +	strcat(_cmdline,*iso);
  20.114 +	if (magic < 0x20630)
  20.115 +		init = ""; // Does not support multiple initramfs
  20.116 +
  20.117 +	if (magic > 0) {
  20.118 +		char *initrd = fallback;
  20.119 +
  20.120 +		if (rootfs[0]) {
  20.121 +			initrd = rootfs;
  20.122 +			if (rootfs[6] != '.' && isoopen("rootfs.gz") >= 0)
  20.123 +				addinitrd();	// for loram
  20.124 +		}
  20.125 +		if (isoopen(initrd) >= 0) {
  20.126 +			addinitrd();
  20.127 +		}
  20.128 +		if (*init && lseek(isofd, 20L, SEEK_SET) != -1 &&
  20.129 +		    read(isofd, &isofileofs, 4) == 4 &&
  20.130 +		    read(isofd, &magic, 4) == 4) {
  20.131 +			isofileofs &= 0xFFFFL;
  20.132 +			isofilesize = magic & 0xFFFFL;
  20.133 +			isofileofs -= 0xC0L + isofilesize;
  20.134 +			if (isofilesize) addinitrd();
  20.135 +			else init="";
  20.136 +		}
  20.137 +		load_initrds();
  20.138 +		strcat(_cmdline,init);
  20.139 +		strcat(_cmdline," mode=");
  20.140 +		strcat(_cmdline,mode);
  20.141 +		strcat(_cmdline," magic=");
  20.142 +		strcat(_cmdline,ultoa(magic));
  20.143 +	}
  20.144 +	if (isknoppix) {
  20.145 +		if (iso[0][1] == ':')
  20.146 +			*iso += 2;
  20.147 +		for (s = *iso; *s; s++)
  20.148 +			if (*s == '\\') *s = '/';
  20.149 +	}
  20.150 +	close(isofd);
  20.151 +	boot_kernel();
  20.152 +}
  20.153 +
  20.154 +u16 root_dev;
  20.155 +u16 vid_mode;
  20.156 +const char* kernel_name = "bzImage";
  20.157 +const char* initrd_name;
  20.158 +int main(int argc, char *argv[])
  20.159 +{
  20.160 +	char *iso = NULL;
  20.161 +	argv[0] = progname();
  20.162 +	bootiso(argv);	// iso ? parsing is /init.exe stuff !
  20.163 +	if (argc >= 2)
  20.164 +		bootiso(argv + 1);
  20.165 +
  20.166 +	chdirname(*argv);
  20.167 +	if (argc < 2) {
  20.168 +dousage:
  20.169 +		usage();
  20.170 +	}
  20.171 +	for (int i=1; i < argc; i++) {
  20.172 +		char *s=argv[i];
  20.173 +		if (strhead(s,"kernel=") == 0)
  20.174 +			kernel_name = s + 7;
  20.175 +		if (strhead(s,"image=") == 0)
  20.176 +			kernel_name = s + 6;
  20.177 +		else if (strhead(s,"initrd=") == 0)
  20.178 +			initrd_name = s + 7;
  20.179 +		else if (strhead(s,"bootfrom=") == 0)
  20.180 +			iso = s + 9;
  20.181 +		else if (strhead(s,"iso=") == 0)
  20.182 +			iso = s + 4;
  20.183 +		else if(strhead(s,"vga=") == 0) {
  20.184 +			s+=4;
  20.185 +			const char c = *s|0x20;
  20.186 +			if (c == 'a') vid_mode = -3;
  20.187 +			else if (c == 'e') vid_mode = -2;
  20.188 +			else if (c == 'n') vid_mode = -1;
  20.189 +			else vid_mode = strtol(s);
  20.190 +		}
  20.191 +		else if(strhead(s,"-f") == 0) {
  20.192 +			skip_xmmalloc++;
  20.193 +		}
  20.194 +		else {
  20.195 +			if(strhead(s,"root=") == 0) {
  20.196 +				root_dev = strtol(s+5);
  20.197 +			}
  20.198 +			if(strhead(s,"mem=") == 0) {
  20.199 +				topmem = strtol(s+4);
  20.200 +			}
  20.201 +			if (_cmdline[0]) strcat(_cmdline," ");
  20.202 +			strcat(_cmdline,s);
  20.203 +		}
  20.204 +	}
  20.205 +	if (iso && isoreset(iso) >= 0) {
  20.206 +		char *s = (char *) initrd_name;
  20.207 +		if (isoopen((char *) kernel_name) >= 0) {
  20.208 +			isokernel();
  20.209 +			load_kernel();
  20.210 +		}
  20.211 +		if (s) {
  20.212 +			while (*s) {
  20.213 +				char *p, c;
  20.214 +				for (p = s; *s && *s != ','; s++);
  20.215 +				c = *s; *s = 0;
  20.216 +				if (isoopen(p) >= 0) {
  20.217 +					addinitrd();
  20.218 +				}
  20.219 +				*s = c;
  20.220 +				if (c) s++;
  20.221 +			}
  20.222 +			load_initrds();
  20.223 +		}
  20.224 +	}
  20.225 +	else {
  20.226 +		load_kernel();
  20.227 +		load_initrd();
  20.228 +	}
  20.229 +	boot_kernel();
  20.230 +	return _AX;
  20.231 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/linld/stuff/src/XMM.ASM	Tue Nov 22 21:19:01 2016 +0100
    21.3 @@ -0,0 +1,117 @@
    21.4 +;***************************************************************
    21.5 +;****** This file is distributed under GPL
    21.6 +;***************************************************************
    21.7 +                ideal
    21.8 +                %crefref
    21.9 +                %noincl
   21.10 +                %nomacs
   21.11 +                p386
   21.12 +
   21.13 +        group   DGROUP  _TEXT,_BSS
   21.14 +        assume  cs:DGROUP,ds:DGROUP
   21.15 +
   21.16 +        segment _BSS byte public use16 'BSS'
   21.17 +
   21.18 +        global  xmm_handler:dword
   21.19 +xmm_handler	dd	?
   21.20 +
   21.21 +        ends    _BSS
   21.22 +
   21.23 +        segment _TEXT byte public use16 'CODE'
   21.24 +
   21.25 +;***************************************************************
   21.26 +;void enable_a20_xmm();
   21.27 +;***************************************************************
   21.28 +        global  _enable_a20_xmm:near
   21.29 +        proc    _enable_a20_xmm near
   21.30 +
   21.31 +                mov     ah,03h          ;global enable a20
   21.32 +                call    xmm_driver      ;
   21.33 +                mov     ah,05h          ;local enable a20
   21.34 +                ;jmp     xmm_driver      ;
   21.35 +
   21.36 +        endp    _enable_a20_xmm
   21.37 +
   21.38 +;***************************************************************
   21.39 +;Call xmm driver addr or 0 if no xmm
   21.40 +;void xmm_driver()
   21.41 +;***************************************************************
   21.42 +        global  xmm_driver:near
   21.43 +        proc    xmm_driver near
   21.44 +
   21.45 +		cmp	[xmm_handler],0
   21.46 +		jne	@@gotit
   21.47 +
   21.48 +		xchg	ax,cx			; save cmd
   21.49 +                mov     ax,4300h
   21.50 +                int     2fh
   21.51 +                mov     bx,offset xmm_fail
   21.52 +                push    cs
   21.53 +                pop     es
   21.54 +                cmp     al,80h
   21.55 +                jne     @@err
   21.56 +                mov     ax,4310h
   21.57 +                int     2fh
   21.58 +@@err:
   21.59 +		xchg	ax,cx			; restore cmd
   21.60 +		push	es
   21.61 +		push	bx
   21.62 +		pop	[xmm_handler]
   21.63 +@@gotit:
   21.64 +		call	[xmm_handler]
   21.65 +                ret
   21.66 +        endp    xmm_driver
   21.67 +
   21.68 +
   21.69 +;***************************************************************
   21.70 +;u32 xmm_alloc(void* drv, u32 size)
   21.71 +;***************************************************************
   21.72 +        global  _xmm_alloc:near
   21.73 +        proc    _xmm_alloc near
   21.74 +
   21.75 +                pop     bx
   21.76 +		ifndef	NO386
   21.77 +                pop     edx
   21.78 +                push    edx
   21.79 +                dec     edx
   21.80 +                shr     edx,10          ; to Kb
   21.81 +		else
   21.82 +                pop     ax
   21.83 +                pop     dx
   21.84 +                push    dx
   21.85 +                push    ax
   21.86 +		sub	ax,1
   21.87 +		sbb	dx,0
   21.88 +		mov	cx,10
   21.89 +@@tokblp:
   21.90 +		shr	dx,1
   21.91 +		rcr	ax,1
   21.92 +		loop	@@tokblp
   21.93 +		endif
   21.94 +                inc     dx
   21.95 +                push    cs
   21.96 +                push    bx
   21.97 +                mov     ah,09h          ;allocate blk
   21.98 +                call    xmm_driver      ;
   21.99 +                dec     ax
  21.100 +                jnz     @@err
  21.101 +                                        ;now: dx=handle of the blk
  21.102 +                mov     ah,0Ch          ;lock blk
  21.103 +                call    xmm_driver      ;
  21.104 +                dec     ax
  21.105 +                                        ;now: dx:bx=addr of blk
  21.106 +                xchg    ax,bx
  21.107 +                jz      @@ok
  21.108 +@@err:
  21.109 +xmm_fail:
  21.110 +                xor     ax,ax
  21.111 +                cwd
  21.112 +@@ok:
  21.113 +                retf
  21.114 +        endp    _xmm_alloc
  21.115 +
  21.116 +        ends    _TEXT
  21.117 +
  21.118 +        end
  21.119 +
  21.120 +;###### END OF FILE ############################################
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/linld/stuff/src/_BEG.ASM	Tue Nov 22 21:19:01 2016 +0100
    22.3 @@ -0,0 +1,139 @@
    22.4 +;***************************************************************
    22.5 +;****** This file is distributed under GPL
    22.6 +;***************************************************************
    22.7 +                ideal
    22.8 +                %crefref
    22.9 +                %noincl
   22.10 +                %nomacs
   22.11 +                p386
   22.12 +
   22.13 +        group   DGROUP  _TEXT,_DATA,_BSS
   22.14 +        assume  cs:DGROUP,ds:DGROUP
   22.15 +
   22.16 +        segment _TEXT byte public use16 'CODE'
   22.17 +
   22.18 +                org     100h
   22.19 +        global  _text_start:byte
   22.20 +        label   _text_start byte
   22.21 +		extrn	_bss_end
   22.22 +;***************************************************************
   22.23 +; clear bss
   22.24 +;***************************************************************
   22.25 +		xor	ax,ax
   22.26 +		mov	di,offset _bss_start
   22.27 +clearbss:
   22.28 +		mov	[di],al
   22.29 +		inc	di
   22.30 +		cmp	di,sp			; clear bss + heap
   22.31 +		jbe	clearbss
   22.32 +		mov	di,offset _bss_end
   22.33 +;***************************************************************
   22.34 +; build argv & argc
   22.35 +;***************************************************************
   22.36 +;               push	ax			; envp (int 20h do it for us)
   22.37 +                ;mov	[word di],ax		; argv[0] = 0
   22.38 +                mov	si,80h
   22.39 +                cld
   22.40 +                lodsb
   22.41 +                cmp	al,7Eh
   22.42 +                jbe	alok
   22.43 +                mov	al,7Eh
   22.44 +alok:
   22.45 +		xchg	ax,bx
   22.46 +                mov	[bx+si],bh		; set eos
   22.47 +argbuild:
   22.48 +                mov	bx,2			; argc * 2
   22.49 +argeos:
   22.50 +                mov	dl,1			; look for a start of string
   22.51 +                mov	[byte si-1],bh		; mark eos
   22.52 +                mov	ah,20h			; space will be eos
   22.53 +arglp:
   22.54 +                lodsb
   22.55 +                cmp	al,0h
   22.56 +                je	argdone
   22.57 +                cmp	al,20h
   22.58 +                jb	argeos
   22.59 +                cmp	al,ah
   22.60 +                je	argeos
   22.61 +                cmp	al,27h
   22.62 +                je	isargstr
   22.63 +                cmp	al,22h
   22.64 +                je	isargstr
   22.65 +                or	dl,dl
   22.66 +                je	arglp			; not start of string
   22.67 +                dec	si
   22.68 +                jmp	newarg
   22.69 +isargstr:
   22.70 +                mov	ah,al			; expected eos
   22.71 +newarg:
   22.72 +                mov	[word bx+di],si		; argv[argc++] = si
   22.73 +                inc	bx
   22.74 +                inc	bx
   22.75 +                dec	dx
   22.76 +                jmp	arglp
   22.77 +argdone:
   22.78 +                ;mov	[word bx+di],0		; argv[argc] = 0
   22.79 +		lea	si,[bx+di+2]
   22.80 +		extrn	_heap_top:word
   22.81 +		mov	[_heap_top],si
   22.82 +                push	di			; argv
   22.83 +                shr	bx,1
   22.84 +                push	bx			; argc
   22.85 +	ifndef	filearg
   22.86 +                mov	bx,[di+2]		; argv[1]
   22.87 +                cmp	[byte bx],'@'
   22.88 +		jne	argend
   22.89 +                inc	bx			; al=0 RDONLY
   22.90 +		extrn	open:near
   22.91 +		call	near open
   22.92 +		jc	argend
   22.93 +		pop	bx			; trash argc,  argv >> 1Kb !
   22.94 +		push	di
   22.95 +		push	ax
   22.96 +		extrn	_read:near
   22.97 +		call	near _read
   22.98 +                pop	bx			; fd for close
   22.99 +                pop	si			; si=buffer=argv
  22.100 +                add	di,ax
  22.101 +                pop	ax			; trash sizemax=argv
  22.102 +		extrn	close:near
  22.103 +		call	near close
  22.104 +                jmp	argbuild
  22.105 +argend:
  22.106 +	endif
  22.107 +
  22.108 +;***************************************************************
  22.109 +                extrn   _is_vm86:near
  22.110 +                call    _is_vm86		; load_image needs that
  22.111 +
  22.112 +;***************************************************************
  22.113 +                extrn   _main:near
  22.114 +                call    _main
  22.115 +                push	ax
  22.116 +                push	ax
  22.117 +;***************************************************************
  22.118 +;void exit(int n);
  22.119 +;***************************************************************
  22.120 +	        global  _exit:near
  22.121 +	        global  exit:near
  22.122 +_exit:
  22.123 +		pop	bx			;caller return address
  22.124 +                pop	ax			; n
  22.125 +exit:
  22.126 +                mov	ah,4Ch
  22.127 +                int	21h
  22.128 +        ends    _TEXT
  22.129 +
  22.130 +        segment _DATA byte public use16 'DATA'
  22.131 +        global  _data_start:byte
  22.132 +        label   _data_start byte
  22.133 +        ends    _DATA
  22.134 +
  22.135 +        segment _BSS byte public use16 'BSS'
  22.136 +        global  _bss_start:byte
  22.137 +        label   _bss_start byte
  22.138 +        ends    _BSS
  22.139 +
  22.140 +        end     _text_start
  22.141 +
  22.142 +;###### END OF FILE ############################################