wok-next rev 13691

syslinux: add iso2exe
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Dec 13 14:33:27 2012 +0100 (2012-12-13)
parents 351e5fac42ac
children 87a217af01ea
files syslinux-extra/receipt syslinux/receipt syslinux/stuff/iso2exe/Makefile syslinux/stuff/iso2exe/README syslinux/stuff/iso2exe/boot.c syslinux/stuff/iso2exe/bootiso.S syslinux/stuff/iso2exe/bootlinux.c syslinux/stuff/iso2exe/bootlinux.h syslinux/stuff/iso2exe/init syslinux/stuff/iso2exe/iso2exe.sh syslinux/stuff/iso2exe/iso9660.c syslinux/stuff/iso2exe/iso9660.h syslinux/stuff/iso2exe/libdos.c syslinux/stuff/iso2exe/libdos.h syslinux/stuff/iso2exe/lzcom.S syslinux/stuff/iso2exe/unlzma.S
line diff
     1.1 --- a/syslinux-extra/receipt	Wed Dec 12 16:59:24 2012 -0500
     1.2 +++ b/syslinux-extra/receipt	Thu Dec 13 14:33:27 2012 +0100
     1.3 @@ -8,7 +8,7 @@
     1.4  WANTED="syslinux"
     1.5  WEB_SITE="http://syslinux.zytor.com/"
     1.6  
     1.7 -DEPENDS="syslinux"
     1.8 +DEPENDS="syslinux posixovl"
     1.9  BUILD_DEPENDS="lzma"
    1.10  
    1.11  # Rules to gen a SliTaz package suitable for Tazpkg.
    1.12 @@ -24,5 +24,6 @@
    1.13      cp -a $src/linux/syslinux-nomtools $fs/bin/syslinux
    1.14      cp -a $src/extlinux/extlinux $fs/bin
    1.15      cp -a $src/isohybrid.sh $fs/usr/bin/isohybrid
    1.16 +    cp -a $src/iso2exe/iso2exe $fs/usr/bin/iso2exe
    1.17      chown root.root $fs/usr/share/boot/* $fs/bin/* $fs/usr/bin/*
    1.18  }
     2.1 --- a/syslinux/receipt	Wed Dec 12 16:59:24 2012 -0500
     2.2 +++ b/syslinux/receipt	Thu Dec 13 14:33:27 2012 +0100
     2.3 @@ -8,7 +8,7 @@
     2.4  TARBALL="$PACKAGE-$VERSION.tar.xz"
     2.5  WEB_SITE="http://syslinux.zytor.com/"
     2.6  WGET_URL="ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux/$TARBALL"
     2.7 -BUILD_DEPENDS="kbd-base perl nasm"
     2.8 +BUILD_DEPENDS="kbd-base perl nasm dev86 lzma"
     2.9  DEPENDS="gpxe memtest"
    2.10  CONFIG_FILES="/boot/isolinux"
    2.11  
    2.12 @@ -16,6 +16,8 @@
    2.13  compile_rules()
    2.14  {
    2.15      cd $src
    2.16 +    cp -a $stuff/iso2exe .
    2.17 +    make -C iso2exe
    2.18      cp $stuff/tools/isohybrid.sh .
    2.19      cp $stuff/tools/keytab-lilo.pl .
    2.20      cp $stuff/extra/md5sum.c com32/modules
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/syslinux/stuff/iso2exe/Makefile	Thu Dec 13 14:33:27 2012 +0100
     3.3 @@ -0,0 +1,34 @@
     3.4 +GCC=gcc -m32
     3.5 +BCC=bcc -ansi -O -0 -C-t
     3.6 +BCCFLAGS=-D__MSDOS__ -Md
     3.7 +
     3.8 +iso2exe: iso2exe.sh bootiso.bin lzcom.bin boot.com init
     3.9 +	cp iso2exe.sh $@
    3.10 +	chmod +x $@
    3.11 +	lzma e boot.com boot.com.lzma -eos
    3.12 +	./$@ --build bootiso.bin lzcom.bin boot.com.lzma init
    3.13 +
    3.14 +OBJS = boot.o iso9660.o libdos.o bootlinux.o
    3.15 +boot.com: $(OBJS)
    3.16 +	$(BCC) $(BCCFLAGS) -o $@ $(OBJS)
    3.17 +
    3.18 +boot.o: boot.c iso9660.h bootlinux.h libdos.h
    3.19 +
    3.20 +bootlinux.o: bootlinux.c iso9660.h bootlinux.h
    3.21 +
    3.22 +iso9660.o: iso9660.c iso9660.h
    3.23 +
    3.24 +libdos.o: libdos.c libdos.h
    3.25 +
    3.26 +lzcom.bin: lzcom.S unlzma.S
    3.27 +
    3.28 +%.o: %.c
    3.29 +	$(BCC) $(BCCFLAGS) -A-l -A$*.lst -c -o $@ $<
    3.30 +
    3.31 +%.bin: %.S
    3.32 +	$(GCC) -D__ASSEMBLY__ -Wa,-acghlnm=$*.lst -c -o $*.o $<
    3.33 +	objcopy -O binary $*.o $@
    3.34 +	chmod +x $@
    3.35 +
    3.36 +clean:
    3.37 +	rm -f *.bin *.o *~ 
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/syslinux/stuff/iso2exe/README	Thu Dec 13 14:33:27 2012 +0100
     4.3 @@ -0,0 +1,84 @@
     4.4 +The iso2exe tool inserts a DOS .EXE header in an ISO image.
     4.5 +The ISO image can be launched by DOS :
     4.6 +
     4.7 +C:\> ren slitaz-5.0.iso slitaz.exe
     4.8 +C:\> slitaz
     4.9 +
    4.10 +
    4.11 +Why ?
    4.12 +
    4.13 +According to the SliTaz forum, some new users have problems to burn CD-ROM,
    4.14 +create USB Keys, and boot these devices with the BIOS. Others are lost during 
    4.15 +installation process or partitionning.
    4.16 +
    4.17 +The slitaz.exe program boots the SliTaz ISO image with a text menu:
    4.18 +
    4.19 +- to start SliTaz in RAM (live) in graphic mode or text mode.
    4.20 +
    4.21 +- to install SliTaz "a la UMSDOS" in the \slitaz\ subdirectory. The simplest
    4.22 +  way install to SliTaz. No partionning. No questions.
    4.23 +
    4.24 +
    4.25 +Usage:
    4.26 +
    4.27 +  C:\> progname [mode]
    4.28 +
    4.29 +Default mode is menu. mode can be:
    4.30 +
    4.31 +- menu	  	start with an interactive menu
    4.32 +- live    	launch SliTaz in RAM with graphics
    4.33 +- text    	launch SliTaz in RAM with text mode
    4.34 +- install 	SliTaz UMSDOS like installation
    4.35 +
    4.36 +If the progname name includes one of the supported mode, the according mode is
    4.37 +assumed. Example 'C:\> slitazlive.exe' starts SliTaz in RAM with graphics.
    4.38 +
    4.39 +
    4.40 +Implementation:
    4.41 +
    4.42 +ISO9660 format begins with 32Kb unused (16 sectors). Some programs may use it:
    4.43 +
    4.44 +- isolinux uses the first 512 bytes for hybrid iso boot (ISO image in a 
    4.45 +  partition).
    4.46 +- tazlito stores flavor extra infos at the 2nd Kb for 'tazlito iso2flavor'.
    4.47 +
    4.48 +The iso2exe tool moves the isolinux boot sector, installs its own boot sector 
    4.49 +with a DOS .EXE header, and adds a DOS .COM Linux loader and an initramfs in 
    4.50 +the end of the first 32Kb.
    4.51 +
    4.52 +    +-----------------+
    4.53 +    |    untouched    | ISO9660 files including /boot/bzImage and /boot/rootfs*
    4.54 +32K +-----------------+
    4.55 +    |  ISO initramfs  | Live loader and UMSDOS like install script
    4.56 +    +-----------------+
    4.57 +    | DOS .COM loader | Load bzImage, the last rootfs*.gz and the ISO initramfs
    4.58 +    +-----------------+
    4.59 +           unused
    4.60 +    +-----------------+
    4.61 +    |  tazlito info   | Flavor missing datas for 'tazlito iso2flavor'
    4.62 + 1K +-----------------+
    4.63 +    | isohybrid boot  | Starts isolinux.bin
    4.64 +512 +-----------------+
    4.65 +    |  iso2exe boot   |	Boot starts isohybrid (*), .EXE starts DOS .COM loader
    4.66 +  0 +-----------------+
    4.67 +
    4.68 +* Eltorito boot (i.e. bootable CD-ROM by BIOS) is not concerned by iso2exe.
    4.69 +
    4.70 +
    4.71 +Limitations:
    4.72 +
    4.73 +- Real mode support only. VM86 is not (yet?) supported
    4.74 +
    4.75 +- Image/zImage format not supported. bzImage only. Can't boot memtest or gpxe.
    4.76 +
    4.77 +- The tiny Linux loader can't load more than 15Mb of files. (not really a 
    4.78 +  problem since many-in-1 ISO format).
    4.79 +
    4.80 +- The DOS Linux loader and the ISO initramfs must fit in ~30Kb.
    4.81 +
    4.82 +- Old Linux kernels don't support multiple initramfs load. They will not
    4.83 +  find the /init.exe file. As workaround, you can add the "text" argument:
    4.84 +	C:\> slitaz.exe text
    4.85 +
    4.86 +- The ISO image must include the files /boot/bzImage and /boot/rootfs*
    4.87 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/syslinux/stuff/iso2exe/boot.c	Thu Dec 13 14:33:27 2012 +0100
     5.3 @@ -0,0 +1,162 @@
     5.4 +#include <asm/limits.h>
     5.5 +#include <sys/types.h>
     5.6 +#include <unistd.h>
     5.7 +#include <fcntl.h>
     5.8 +#include <stdio.h>
     5.9 +#include "iso9660.h"
    5.10 +#include "bootlinux.h"
    5.11 +#include "libdos.h"
    5.12 +
    5.13 +static void usage(char *iso)
    5.14 +{
    5.15 +	printf("Usage: %s [[@commands]|[kernel=<bzimage>] \
    5.16 +[initrd=<rootfs>[,<rootfs2>...]] [iso=<isofile>] ...]\n\n\
    5.17 +Defaults: %s @tazboot.cmd  or  %s kernel=bzImage auto\n\n\
    5.18 +Examples for tazboot.cmd:\n\n\
    5.19 +  iso=\\isos\\slitaz-4.0.iso\n\
    5.20 +  kernel=boot/bzImage\n\
    5.21 +  initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz\n\
    5.22 +  rw root=/dev/null vga=normal autologin\n\n\
    5.23 +  kernel=\\slitaz\\vmlinuz\n\
    5.24 +  root=/dev/sda5 ro\n",iso,iso,iso);
    5.25 +	exit(1);
    5.26 +}
    5.27 +
    5.28 +static void bootiso(char **iso)
    5.29 +{
    5.30 +	char *init = "rdinit=/init.exe", *mode="menu";
    5.31 +	char c, *s, rootfs[16], cmdline[256];
    5.32 +	int fd, restart;
    5.33 +	unsigned long magic;
    5.34 +	
    5.35 +	if (isoreset(*iso) || isoopen("boot")) return;
    5.36 +	if (iso[1] && !strcmp(mode = iso[1], "text"))
    5.37 +		init = "";
    5.38 +	for (c = 0, restart = 1; isoreaddir(restart) == 0; restart = 0) {
    5.39 +		if (strncmp(isofilename, "rootfs", 6) || c > s[6]) continue;
    5.40 +		strcpy(rootfs, isofilename);
    5.41 +		c = s[6];
    5.42 +	}
    5.43 +	if (isoopen(mode))
    5.44 +		isoopen("bzImage");
    5.45 +	loadkernel();
    5.46 +	isoopen(rootfs);
    5.47 +	loadinitrd();
    5.48 +	lseek(isofd, 28, SEEK_SET);
    5.49 +	read(isofd, &magic, 4);
    5.50 +	isofilesize = magic & 0xFFFF;
    5.51 +	isofileofs = 0x8000 - isofilesize;
    5.52 +	loadinitrd();
    5.53 +	close(isofd);
    5.54 +	sprintf(cmdline,"rw root=/dev/null %s iso=%s magic=%lu mode=%s",
    5.55 +		init, *iso, magic, mode);
    5.56 +	bootlinux(cmdline);
    5.57 +}
    5.58 +
    5.59 +static int stricmp(char *ref, char *s)
    5.60 +{
    5.61 +	char c;
    5.62 +	while (*ref) {
    5.63 +		c = *s++;
    5.64 +		if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
    5.65 +		c -= *ref++;
    5.66 +		if (c) return c;
    5.67 +	}
    5.68 +	return 0;
    5.69 +}
    5.70 +
    5.71 +static char *iso;
    5.72 +static int fakeopen(char *file)
    5.73 +{
    5.74 +	if (iso) {
    5.75 +		isoreset(iso);
    5.76 +		return isoopen(file);
    5.77 +	}
    5.78 +	close(isofd);
    5.79 +	isofd = open(file, O_RDONLY);
    5.80 +	if (isofd != -1) {
    5.81 +		isofileofs = 0;
    5.82 +		isofilesize = LONG_MAX;
    5.83 +	}
    5.84 +	return isofd;
    5.85 +}
    5.86 +
    5.87 +static char args[2048];
    5.88 +int main(int argc, char *argv[])
    5.89 +{
    5.90 +	char *kernel, *initrd, *cmdline, *cmdfile, *s;
    5.91 +	
    5.92 +	argv[0] = progname();
    5.93 +	bootiso(argv);		// iso ? parsing is /init.exe stuff !
    5.94 +
    5.95 +	chdirname(*argv);
    5.96 +	cmdfile = "tazboot.cmd";
    5.97 +	kernel  = "bzImage";
    5.98 +	initrd  = NULL;
    5.99 +	cmdline = "auto";
   5.100 +	if (argc > 1) {
   5.101 +		if (argv[1][0] == '@')
   5.102 +			cmdfile = argv[1] + 1;
   5.103 +		else {
   5.104 +			cmdfile = NULL;
   5.105 +#asm
   5.106 +		push	ds
   5.107 +		push	ds
   5.108 +		pop	es
   5.109 +		push	cs
   5.110 +		pop	ds
   5.111 +		mov	si, #0x82
   5.112 +		mov	di, #_args
   5.113 +		mov	cx, #0x7E/2
   5.114 +		rep
   5.115 +		  movsw
   5.116 +		pop	ds
   5.117 +#endasm
   5.118 +		}
   5.119 +	}
   5.120 +	if (cmdfile) {
   5.121 +		int fd;
   5.122 +		fd = open(cmdfile, O_RDONLY);;
   5.123 +		if (fd != -1) {
   5.124 +			read(fd, args, sizeof(args));
   5.125 +			close(fd);
   5.126 +			for (s = args; s < args + sizeof(args) -1; s++) {
   5.127 +				if (*s == '\r') *s++ = ' ';
   5.128 +				if (*s == '\n') *s   = ' ';
   5.129 +			}
   5.130 +		}
   5.131 +	}
   5.132 +	for (s = args; s < args + sizeof(args); s++) {
   5.133 +		if (*s == ' ') continue;
   5.134 +		if (stricmp("kernel=", s) == 0)
   5.135 +			kernel = s + 7;
   5.136 +		else if (stricmp("initrd=", s) == 0)
   5.137 +			initrd = s + 7;
   5.138 +		else if (stricmp("iso=", s) == 0)
   5.139 +			iso = s + 4;
   5.140 +		else {
   5.141 +			cmdline = s;
   5.142 +			break;
   5.143 +		}
   5.144 +		while (*s && *s != ' ') s++;
   5.145 +		*s = 0;
   5.146 +	}
   5.147 +	if (fakeopen(kernel) == -1)
   5.148 +		usage(argv[0]);
   5.149 +	loadkernel();
   5.150 +	if (initrd) {
   5.151 +		char *p, *q = initrd;
   5.152 +		while (1) {
   5.153 +			char c;
   5.154 +			for (p = q; *p && *p != ','; p++);
   5.155 +			c = *p;
   5.156 +			*p = 0;
   5.157 +			if (fakeopen(q) != -1)
   5.158 +				loadinitrd();
   5.159 +			if (c == 0)
   5.160 +				break;
   5.161 +			q = ++p;
   5.162 +		}
   5.163 +	}
   5.164 +	bootlinux(cmdline);
   5.165 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/syslinux/stuff/iso2exe/bootiso.S	Thu Dec 13 14:33:27 2012 +0100
     6.3 @@ -0,0 +1,262 @@
     6.4 +	.text
     6.5 +	.code16
     6.6 +	.org	0
     6.7 +
     6.8 +CODESZ	=	0x8000			// 16 sectors = 32Kb
     6.9 +#define EXEADRS(x)	x+0xE0
    6.10 +#define EXESTR(x)	x-0x20
    6.11 +
    6.12 +	.globl	_start
    6.13 +_start:
    6.14 +	decw	%bp			// Magic number: MZ
    6.15 +	popw	%dx
    6.16 +	jmp	start			// Bytes on last page of file
    6.17 +	.word	(CODESZ+511)/512	// Pages in file
    6.18 +	.word	0			// Relocations
    6.19 +	.word	(end_header-_start)/16	// Size of header in paragraphs
    6.20 +	.word	4064-(CODESZ/16)	// Minimum extra paragraphs needed
    6.21 +	.word	4064-(CODESZ/16)	// Maximum extra paragraphs needed
    6.22 +	.word	0xFFF0			// Initial (relative) SS value
    6.23 +	.word	0xFFFE			// Initial SP value
    6.24 +	.word	0			// Checksum
    6.25 +	.word	EXEADRS(fixseg)		// Initial IP value
    6.26 +	.word	0xFFF0			// Initial (relative) CS value
    6.27 +	.word	0x001C			// File address of relocation table
    6.28 +	.word	0			// Overlay number
    6.29 +initramfssize:
    6.30 +	.word	0
    6.31 +id:
    6.32 +	.word	0
    6.33 +end_header:
    6.34 +
    6.35 +chksum:
    6.36 +	.long	0
    6.37 +comstart:
    6.38 +	.word	0
    6.39 +
    6.40 +/////////////////////// Master Boot Record code //////////////////////////////
    6.41 +
    6.42 +start:
    6.43 +	incw	%bp
    6.44 +	pushw	%dx			// restore SP
    6.45 +	pushaw
    6.46 +	movw	%sp, %bp
    6.47 +	pushf
    6.48 +	pushw	%ds
    6.49 +	pushw	%es
    6.50 +	pushw	$0
    6.51 +	popw	%ds
    6.52 +	call	setreg
    6.53 +	rep
    6.54 +	movsw
    6.55 +	ljmp	$0, $0x0600+start2
    6.56 +	
    6.57 +setreg:
    6.58 +	cld
    6.59 +	pushw	%ds
    6.60 +	popw	%es
    6.61 +	movw	$0x7C00, %si
    6.62 +	movw	%si, %bx
    6.63 +	movw	$0x0600, %di
    6.64 +	movw	$0x0100, %cx
    6.65 +return:
    6.66 +	ret
    6.67 +start2:
    6.68 +	movw	$0x80, %dx
    6.69 +dxloop:
    6.70 +	movw	$1, %cx
    6.71 +	movw	$0x201, %ax
    6.72 +	int	$0x13
    6.73 +	jc	next
    6.74 +	call 	setreg
    6.75 +	repe
    6.76 +	cmpsw
    6.77 +	je	dxfound
    6.78 +next:
    6.79 +	addb	$0x7D, %dl		// try every hard disk
    6.80 +	andb	$0x83, %dl		//   and floppy disk
    6.81 +	cmpb	$0x80, %dl
    6.82 +	jnz	dxloop
    6.83 +fail:
    6.84 +	int	$0x19
    6.85 +dxfound:
    6.86 +	movw	%dx, 10(%bp)
    6.87 +	movb	$2, %cl			// %ch = 0
    6.88 +	movw	$0x201, %ax
    6.89 +	int	$0x13
    6.90 +	jc	fail
    6.91 +	cmpw	$0xAA55, 0x7DFE
    6.92 +	jne	fail
    6.93 +	popw	%es
    6.94 +	popw	%ds
    6.95 +	popf
    6.96 +	popa
    6.97 +	ljmp	$0, $0x7C00
    6.98 +
    6.99 +////////////////////////////// DOS EXE code ///////////////////////////////////
   6.100 +
   6.101 +no386:
   6.102 +	.ascii	"No 386+$"
   6.103 +noDOS3:
   6.104 +	.ascii	"No DOS 3.0+$"
   6.105 +rmPaging:
   6.106 +	.ascii	"Broken paging.$"
   6.107 +ERRvcpi:
   6.108 +	.ascii	"No VCPI 4.0+$"
   6.109 +chkerr:
   6.110 +	.ascii	"Broken ISO.$"
   6.111 +realmodemsg:
   6.112 +	.ascii	"Real mode\r$"
   6.113 +vm86modemsg:
   6.114 +	.ascii	"Vm86\r$"
   6.115 +help:
   6.116 +	.ascii	"Linux kickstarter.\r\n$"
   6.117 +fixseg:
   6.118 +#if 1
   6.119 +	movb	$EXESTR(help), %dl
   6.120 +	movw	0x82, %ax
   6.121 +	cmpw	$0x3F2F, %ax		# /?
   6.122 +	je	abort
   6.123 +#endif
   6.124 +	pushf
   6.125 +	popw	%ax
   6.126 +	movw	$0xF0F0, %cx
   6.127 +	orb	%ah, %ch
   6.128 +	andb	$0xF, %ah
   6.129 +	
   6.130 +	pushw	%ax
   6.131 +	popf
   6.132 +	pushf
   6.133 +	popw	%ax
   6.134 +	andb	%cl, %ah
   6.135 +	
   6.136 +	cmp	%cl, %ah
   6.137 +	je	NotSupported	// 8086 family
   6.138 +	
   6.139 +	pushw	%cx
   6.140 +	popf
   6.141 +	pushf
   6.142 +	popw	%ax
   6.143 +	andb	%cl, %ah
   6.144 +	
   6.145 +	jnz	is386		// 80286 family
   6.146 +NotSupported:
   6.147 +	movb	$EXESTR(no386), %dl
   6.148 +abort:
   6.149 +puts:
   6.150 +	movb	$1, %dh
   6.151 +	movb	$9, %ah
   6.152 +	int	$0x21
   6.153 +	ret
   6.154 +
   6.155 +is386:
   6.156 +	movb	$0x30, %ah
   6.157 +	int	$0x21
   6.158 +	cmpb	$3, %al
   6.159 +	movb	$EXESTR(noDOS3), %dl
   6.160 +	jb	abort
   6.161 +	smsw	%ax
   6.162 +	andb	$1, %al
   6.163 +	jne	tstvcpi
   6.164 +	movl	%cr0, %eax
   6.165 +	movb	$EXESTR(rmPaging), %dl
   6.166 +	shll	$1, %eax
   6.167 +	jc	abort
   6.168 +	jmp	realmode
   6.169 +
   6.170 +tstvcpi:
   6.171 +	pushw	%ds
   6.172 +	pushw	$0
   6.173 +	popw	%ds
   6.174 +	movw	0x67*4+2, %ds
   6.175 +	std
   6.176 +	movw	$14, %si
   6.177 +	lodsl
   6.178 +	cmpl	$0x30585858, %eax	// 0XXX
   6.179 +	lodsl
   6.180 +	cld
   6.181 +	popw	%ds
   6.182 +NoVCPI:
   6.183 +	movb	$EXESTR(ERRvcpi), %dl
   6.184 +goabort:
   6.185 +	jne	abort
   6.186 +	shll	$8, %eax
   6.187 +	cmpl	$0x4D4D4500, %eax	// [XQ]MME
   6.188 +#if 1
   6.189 +	movw	$EXEADRS(CmdVCPI), %si
   6.190 +ChkVCPI:
   6.191 +	jne	NoVCPI
   6.192 +	lodsb
   6.193 +	shlw	$8, %ax
   6.194 +	je	VersionVCPI
   6.195 +	int	$0x67
   6.196 +	jmp	ChkVCPI
   6.197 +CmdVCPI:
   6.198 +	.byte	0x40			// status
   6.199 +	.byte	0xDE			// vcpi present ?
   6.200 +	.byte	0x46			// version
   6.201 +	.byte	0
   6.202 +VersionVCPI:
   6.203 +	cmpb	$0x40, %al		// >= 4.0 ?
   6.204 +	jb	NoVCPI
   6.205 +#else
   6.206 +	jne	NoVCPI
   6.207 +	movb	$0x40, %ah		// status
   6.208 +	int	$0x67
   6.209 +	testb	%ah, %ah
   6.210 +	jne	NoVCPI
   6.211 +	movb	$0x46, %ah		// version
   6.212 +	int	$0x67
   6.213 +	testb	%ah, %ah
   6.214 +	jne	NoVCPI
   6.215 +	cmpb	$0x40, %al		// >= 4.0 ?
   6.216 +	jb	NoVCPI
   6.217 +	movw	$0xDE00, %ax		// vcpi present ?
   6.218 +	int	$0x67
   6.219 +	testb	%ah, %ah
   6.220 +	jne	NoVCPI
   6.221 +#endif
   6.222 +realmode:
   6.223 +	movw	$0x100, %si
   6.224 +	lodsl
   6.225 +	xchgl	%eax, %edx
   6.226 +	orl	%edx, %edx
   6.227 +	jz	skip
   6.228 +	movw	$0x7FDC/4, %cx
   6.229 +chklp:
   6.230 +	lodsl
   6.231 +	addl	%eax, %edx
   6.232 +	loop	chklp
   6.233 +	orl	%edx, %edx
   6.234 +	movb	$EXESTR(chkerr), %dl
   6.235 +	jne	goabort
   6.236 +skip:
   6.237 +	movb	$EXESTR(realmodemsg), %dl
   6.238 +	smsww	%ax
   6.239 +	andb	$1, %al
   6.240 +	jz	isrealmode
   6.241 +	movb	$EXESTR(vm86modemsg), %dl
   6.242 +isrealmode:
   6.243 +	call	puts
   6.244 +	movw	EXEADRS(comstart), %ax			// .com address
   6.245 +
   6.246 +	cld
   6.247 +	movw	$moveend-move, %cx
   6.248 +	movw	$EXEADRS(move), %si
   6.249 +	movw	$0xC000, %di
   6.250 +	jmp	move2
   6.251 +
   6.252 +move:
   6.253 +	movb	$0x80, %ch
   6.254 +	xchgw	%ax, %si
   6.255 +	movw	$0x0100, %di
   6.256 +move2:
   6.257 +	pushw	%di
   6.258 +	rep
   6.259 +	movsb
   6.260 +	ret
   6.261 +moveend:
   6.262 +	
   6.263 +	.org	440
   6.264 +//////////////////////////// partition table //////////////////////////////////
   6.265 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/syslinux/stuff/iso2exe/bootlinux.c	Thu Dec 13 14:33:27 2012 +0100
     7.3 @@ -0,0 +1,258 @@
     7.4 +#include <stdio.h>
     7.5 +#include "iso9660.h"
     7.6 +
     7.7 +static unsigned version;
     7.8 +#define SETUPSECTORS	0x1F1
     7.9 +#define ROFLAG		0x1F2
    7.10 +#define SYSSIZE		0x1F4
    7.11 +#define VIDEOMODE	0x1FA
    7.12 +#define BOOTFLAG	0x1FE
    7.13 +#define HEADER		0x202
    7.14 +#define VERSION		0x206
    7.15 +#define RMSWOFS		0x208
    7.16 +#define RMSWSEG		0x20A
    7.17 +#define LOADERTYPE	0x210
    7.18 +#define LOADFLAGS	0x211
    7.19 +#define SYSTEMCODE	0x214
    7.20 +#define INITRDCODE	0x218
    7.21 +#define INITRDSIZE	0x21C
    7.22 +#define HEAPPTR		0x224
    7.23 +#define CMDLINE		0x228
    7.24 +
    7.25 +#define SETUP_SEGMENT	0x9000
    7.26 +#define CMDLINE_OFFSET	0x9E00
    7.27 +
    7.28 +#define BUFFERSZ	2*1024
    7.29 +static char buffer[BUFFERSZ];
    7.30 +static unsigned long initrd_addr, initrd_size;
    7.31 +
    7.32 +static int may_exit_dos = 1;
    7.33 +static void die(char *msg)
    7.34 +{
    7.35 +	printf("%s.\n", msg);
    7.36 +	if (may_exit_dos)
    7.37 +		exit(1);
    7.38 +	while (1);
    7.39 +}
    7.40 +
    7.41 +static int vm86(void)
    7.42 +{
    7.43 +#asm
    7.44 +		smsw	ax
    7.45 +		and	ax, #1		// 0:realmode	1:vm86
    7.46 +#endasm
    7.47 +} 
    7.48 +
    7.49 +static struct mem {
    7.50 +	unsigned long base;
    7.51 +	int align;
    7.52 +} kernelmem = { 0x100000, 0 };
    7.53 +
    7.54 +#define initrdmem kernelmem
    7.55 +
    7.56 +static void movehi(void)
    7.57 +{
    7.58 +#asm
    7.59 +		pusha
    7.60 +		xor	di, di		// 30
    7.61 +		mov	cx, #9		// 2E..1E
    7.62 +zero1:
    7.63 +		push	di
    7.64 +		loop	zero1
    7.65 +		push	dword [_kernelmem]	// 1A p->base
    7.66 +		push	#-1		// 18
    7.67 +		push	di		// 16
    7.68 +		xor	eax, eax
    7.69 +		cdq
    7.70 +		mov	dx, ds
    7.71 +		shl	edx, #4
    7.72 +		mov	ax, #_buffer
    7.73 +		add	edx, eax
    7.74 +		push	edx		// 12 linear_address(buffer)
    7.75 +		push	#-1		// 10
    7.76 +		mov	cl, #8		// 0E..00
    7.77 +zero2:
    7.78 +		push	di
    7.79 +		loop	zero2
    7.80 +		mov	ch, #BUFFERSZ/512
    7.81 +		push	ss
    7.82 +		pop	es
    7.83 +		mov	si, sp
    7.84 +		mov	ax, #0x8793
    7.85 +		mov	[si+0x15], al
    7.86 +		xchg	[si+0x1D], al
    7.87 +		mov	[si+0x1F], al	// bits 24..31, doesn't work for me :(
    7.88 +		int	0x15
    7.89 +		add	sp, #0x30
    7.90 +		popa
    7.91 +#endasm
    7.92 +}
    7.93 +
    7.94 +static void load(struct mem *p, unsigned long size)
    7.95 +{
    7.96 +	if (vm86())
    7.97 +		die("Need real mode");
    7.98 +	switch (p->align) {
    7.99 +	case 0:	// kernel
   7.100 +		p->align = 4096;
   7.101 +		break;
   7.102 +	case 4096: // first initrd
   7.103 +		initrd_addr = p->base;
   7.104 +		p->align = 4;
   7.105 +	}
   7.106 +	while (size) {
   7.107 +		int n, s = sizeof(buffer);
   7.108 +		for (n = 0; n < s; n++) buffer[n] = 0;
   7.109 +		if (s > size) s = size;
   7.110 +		n = isoread(buffer, s);
   7.111 +		movehi();
   7.112 +		if (n != -1) {
   7.113 +			p->base += n;
   7.114 +			size -= n;
   7.115 +		}
   7.116 +		if (s != n) break;
   7.117 +	}
   7.118 +	initrd_size = p->base - initrd_addr;
   7.119 +	p->base += p->align - 1;
   7.120 +	p->base &= - p->align;
   7.121 +}
   7.122 +
   7.123 +static unsigned setupofs = 0;
   7.124 +
   7.125 +void movesetup(void)
   7.126 +{
   7.127 +#asm
   7.128 +		pusha
   7.129 +		push	#SETUP_SEGMENT
   7.130 +		pop	es
   7.131 +		mov	si, #_buffer
   7.132 +		mov	di, _setupofs
   7.133 +		mov	cx, #BUFFERSZ/2
   7.134 +		rep
   7.135 +		  movsw
   7.136 +		mov	_setupofs, di
   7.137 +		popa
   7.138 +#endasm
   7.139 +}
   7.140 +
   7.141 +void loadkernel(void)
   7.142 +{
   7.143 +	unsigned setup, n = BUFFERSZ;
   7.144 +	unsigned long syssize = 0;
   7.145 +
   7.146 +	do {
   7.147 +		isoread(buffer, n);
   7.148 +		if (setupofs == 0) {
   7.149 +			if (* (unsigned short *) (buffer + BOOTFLAG) != 0xAA55)
   7.150 +				die("The kernel is not bootable");
   7.151 +			setup = (1 + buffer[SETUPSECTORS]) << 9;
   7.152 +			if (setup == 512) setup = 5 << 9;
   7.153 +			syssize = * (unsigned long  *) (buffer + SYSSIZE) << 4;
   7.154 +			version = * (unsigned short *) (buffer + VERSION);
   7.155 +#define HDRS	0x53726448
   7.156 +			if (* (unsigned long *) (buffer + HEADER) != HDRS)
   7.157 +				version = 0;
   7.158 +			if (!version || !(buffer[LOADFLAGS] & 1)) {
   7.159 +#undef ZIMAGE_SUPPORT	/* Does not work... */
   7.160 +#ifdef ZIMAGE_SUPPORT
   7.161 +#asm
   7.162 +		pusha
   7.163 +		mov	cx, #0x8000
   7.164 +		mov	es, cx
   7.165 +		xor	si, si
   7.166 +		xor	di, di
   7.167 +		rep
   7.168 +		  movsw
   7.169 +		push	es
   7.170 +		pop	ds
   7.171 +		push	es
   7.172 +		pop	ss
   7.173 +		popa
   7.174 +		jmpi	relocated, #0x8000
   7.175 +relocated:
   7.176 +#endasm
   7.177 +				kernelmem.base = 0x10000;
   7.178 +				if (syssize > 0x70000)
   7.179 +#endif
   7.180 +				die("Not a bzImage format");
   7.181 +			}
   7.182 +			if (version < 0x204)
   7.183 +				syssize &= 0x000FFFFFUL;
   7.184 +			if (version) {
   7.185 +#ifdef REALMODE_SWITCH
   7.186 +				* (unsigned short *) (buffer + RMSWOFS) = 
   7.187 +					realmode_switch;
   7.188 +				* (unsigned short *) (buffer + RMSWSEG) = 
   7.189 +					getcs();
   7.190 +#endif
   7.191 +				* (unsigned short *) (buffer + HEAPPTR) = 
   7.192 +					0x9B00;
   7.193 +				// buffer[LOADFLAGS] |= 0x80;
   7.194 +				* (unsigned short *) (buffer + LOADERTYPE) |= 
   7.195 +					0x80FF;
   7.196 +			}
   7.197 +		}
   7.198 +		movesetup();
   7.199 +		setup -= n;
   7.200 +		n = (setup > BUFFERSZ) ? BUFFERSZ : setup;
   7.201 +	} while (setup > 0);
   7.202 +
   7.203 +	load(&kernelmem, syssize);
   7.204 +}
   7.205 +
   7.206 +void loadinitrd(void)
   7.207 +{
   7.208 +	if (version)
   7.209 +		load(&initrdmem, isofilesize);
   7.210 +}
   7.211 +
   7.212 +void bootlinux(char *cmdline)
   7.213 +{
   7.214 +#asm
   7.215 +	push	#SETUP_SEGMENT
   7.216 +	pop	es
   7.217 +	mov	eax, _initrd_addr
   7.218 +	or	eax, eax
   7.219 +	jz	no_initrd
   7.220 +	mov	di, #0x218
   7.221 +	stosd
   7.222 +	mov	eax, _initrd_size
   7.223 +	stosd
   7.224 +no_initrd:
   7.225 +#endasm
   7.226 +	if (cmdline) {
   7.227 +		if (version <= 0x201) {
   7.228 +#asm
   7.229 +		mov	di, #0x0020
   7.230 +		mov	ax, #0xA33F
   7.231 +		stosw
   7.232 +		mov	ax, #CMDLINE_OFFSET
   7.233 +		stosw
   7.234 +#endasm
   7.235 +		}
   7.236 +		else {
   7.237 +#asm
   7.238 +		mov	di, #0x0228
   7.239 +		mov	eax, #SETUP_SEGMENT*16+CMDLINE_OFFSET
   7.240 +		stosd
   7.241 +#endasm
   7.242 +		}
   7.243 +#asm
   7.244 +		xchg	ax, di
   7.245 +		mov	si, .bootlinux.cmdline[bp]
   7.246 +copy:
   7.247 +		lodsb
   7.248 +		stosb
   7.249 +		or	al,al
   7.250 +		jne	copy
   7.251 +#endasm
   7.252 +	}
   7.253 +#asm
   7.254 +	push	es
   7.255 +	pop	ds
   7.256 +	push	ds
   7.257 +	pop	ss
   7.258 +	mov	sp, #CMDLINE_OFFSET
   7.259 +	jmpi	0, #0x9020
   7.260 +#endasm
   7.261 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/syslinux/stuff/iso2exe/bootlinux.h	Thu Dec 13 14:33:27 2012 +0100
     8.3 @@ -0,0 +1,6 @@
     8.4 +#ifndef __BOOTLINUX_H
     8.5 +#define __BOOTLINUX_H
     8.6 +extern void loadkernel(void);
     8.7 +extern void loadinitrd(void);
     8.8 +extern void bootlinux(char *cmdline);
     8.9 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/syslinux/stuff/iso2exe/init	Thu Dec 13 14:33:27 2012 +0100
     9.3 @@ -0,0 +1,251 @@
     9.4 +#!/bin/sh
     9.5 +
     9.6 +DIALOG=dialog
     9.7 +
     9.8 +get()
     9.9 +{
    9.10 +	od -j $1 -N ${3:-4} -t u${3:-4} -An $2
    9.11 +}
    9.12 +
    9.13 +getarg()
    9.14 +{
    9.15 +	sed "/$1=/!d;s/.*$1=\\([^ ]*\\).*/\\1/" /proc/cmdline
    9.16 +}
    9.17 +
    9.18 +gettazboot()
    9.19 +{
    9.20 +	echo "Create $(basename $1) ..."
    9.21 +	O=$(($(get 36 /mnt/$ISO 2) - 0xE0))
    9.22 +	L=$((0x8000 - $(get 28 /mnt/$ISO 2) - $O))
    9.23 +	S=$((32+$L))
    9.24 +	P=$((($S+511)/512))
    9.25 +	E=$((4096-(32*$P)))
    9.26 +	for i in 0x5A4D $(($S%512)) $P 0 2 $E -1 $((${2:-0}-16)) \
    9.27 +			-2 0 256 -16 28 0x6C53 0x5469 0x7A61; do 
    9.28 +		printf '\\\\x%02X\\\\x%02X' $(($i&255)) $((($i>>8)&255)) | \
    9.29 +			xargs echo -en
    9.30 +	done > $1
    9.31 +	dd bs=1 count=$L skip=$(echo $O) if=/mnt/$ISO >> $1 2> /dev/null
    9.32 +}
    9.33 +
    9.34 +checkmagic()
    9.35 +{
    9.36 +	[ -s $1 ] && [ $(getarg magic) == $(get 28 $1) ]
    9.37 +}
    9.38 +
    9.39 +getiso()
    9.40 +{
    9.41 +	blkid | while read dev info ; do
    9.42 +		case "$info" in
    9.43 +		*dos*|*fat*|*ntfs*)
    9.44 +			mount ${dev%:} /mnt
    9.45 +			if checkmagic /mnt/$ISO; then
    9.46 +				mount -o loop,ro /mnt/$ISO /media/cdrom
    9.47 +				echo "Found $ISO on ${dev%:}"
    9.48 +				break
    9.49 +			fi
    9.50 +			umount /mnt ;;
    9.51 +		esac
    9.52 +	done
    9.53 +}
    9.54 +
    9.55 +uncpio()
    9.56 +{
    9.57 +	echo "Extracting $(basename $1) ..."
    9.58 +	case $(get 0 $1 2) in
    9.59 +	*35615)	zcat $1 ;;
    9.60 +	*\ 93)	unlzma -c $1 ;;
    9.61 +	*)	cat $1 ;;
    9.62 +	esac | ( cd ${2:-/} ; cpio -idmu > /dev/null 2>&1 )
    9.63 +}
    9.64 +
    9.65 +getuuid()
    9.66 +{
    9.67 +	dev=$(mount | sed '/ \/mnt /!d;s/ .*//;s|/dev/||;q')
    9.68 +	blkid | sed "/$dev:/!d;s/.*UUID=.\\([^ ]*\\)\".*/\\1/"
    9.69 +}
    9.70 +
    9.71 +mkinitrd()
    9.72 +{
    9.73 +	echo "Create $(basename $1) ..."
    9.74 +	for i in bin lib dev proc tmp mnt etc ; do
    9.75 +		mkdir -p /tmp/fs/$i
    9.76 +	done
    9.77 +	for i in /dev/console /dev/null /dev/tty /dev/tty1 /dev/fuse \
    9.78 +		 /dev/hd* /dev/sd* ; do
    9.79 +		cp -a $i /tmp/fs$i
    9.80 +	done
    9.81 +	for i in /bin/busybox /usr/sbin/mount.posixovl $(which blkid); do
    9.82 +		cp $(LD_TRACE_LOADED_OBJECTS=1 /lib/ld*.so $i | \
    9.83 +		sed 's|.*=> \(.*/lib/l[^ ]*\).*|\1|;/^\//!d') /tmp/fs/lib
    9.84 +		cp $i /tmp/fs/bin
    9.85 +	done
    9.86 +	cp -a /lib/ld-* /tmp/fs/lib
    9.87 +	for i in $(busybox | sed '/Current/,$!d'); do
    9.88 +		ln -s busybox /tmp/fs/bin/${i%,}
    9.89 +	done
    9.90 +	ln -s /proc/mounts /tmp/fs/etc/mtab
    9.91 +	cat > /tmp/fs/init <<EOT
    9.92 +#!/bin/sh
    9.93 +
    9.94 +arg()
    9.95 +{
    9.96 +	grep -q \$1 /proc/cmdline &&
    9.97 +	val="\$(sed "s/.*\$1=\\([^ ]*\\).*/\\1/" < /proc/cmdline)" &&
    9.98 +	echo "\$2 \$val"
    9.99 +}
   9.100 +
   9.101 +mount -t proc /proc /proc
   9.102 +arg mount "Mount device"
   9.103 +mount \$( (blkid /dev/?d* || blkid) | grep \$val | sed 's/:.*//;q') /mnt
   9.104 +arg subroot "Change root to directory"
   9.105 +mount.posixovl /mnt/\$val
   9.106 +mount --bind /mnt /mnt/\$val/mnt/dos
   9.107 +LDSO=\$(ls /mnt/\$val/lib/ld-* | sed q)
   9.108 +umount /proc
   9.109 +export LD_LIBRARY_PATH=\$val/lib:\$val/usr/lib:/lib
   9.110 +exec /bin/switch_root /mnt \${LDSO#/mnt/} \$val/usr/sbin/chroot \$val /sbin/init
   9.111 +EOT
   9.112 +	chmod +x /tmp/fs/init
   9.113 +	( cd /tmp/fs ; find * | cpio -o -H newc ) | lzma e $1 -si 2> /dev/null
   9.114 +	rm -rf /tmp/fs
   9.115 +}
   9.116 +
   9.117 +doinstall()
   9.118 +{
   9.119 +	mkdir /mnt/slitaz
   9.120 +	mount.posixovl /mnt/slitaz || return
   9.121 +	mkdir -p /mnt/slitaz/boot /mnt/slitaz/mnt/dos
   9.122 +	for i in $(ls -r /media/cdrom/boot/rootfs*); do
   9.123 +		uncpio $i /mnt/slitaz
   9.124 +	done
   9.125 +	for i in /media/cdrom/boot/bzImage /media/cdrom/boot/*pxe* \
   9.126 +		/media/cdrom/boot/isolinux/he* /media/cdrom/boot/isolinux/opt* \
   9.127 +		/media/cdrom/README /media/cdrom/boot/memtest* ; do
   9.128 +		[ -s $i ] && cp $i /mnt/slitaz/boot
   9.129 +	done
   9.130 +	umount -d /media/cdrom
   9.131 +	gettazboot /mnt/slitaz/boot/tazboot.exe
   9.132 +	mkinitrd /mnt/slitaz/boot/initrd
   9.133 +	cat > /mnt/slitaz/boot/tazboot.cmd <<EOT
   9.134 +kernel=\\slitaz\\boot\\bzimage
   9.135 +initrd=\\slitaz\\boot\\initrd
   9.136 +rw root=/dev/null mount=$(getuuid) subroot=slitaz autologin
   9.137 +EOT
   9.138 +	unix2dos /mnt/slitaz/boot/he* /mnt/slitaz/boot/opt* \
   9.139 +		/mnt/slitaz/boot/README /mnt/slitaz/boot/tazboot.cmd
   9.140 +	[ -x /mnt/slitaz/usr/sbin/mount.posixovl ] ||
   9.141 +	cp /usr/sbin/mount.posixovl /mnt/slitaz/usr/sbin
   9.142 +	! grep -qs tazboot /mnt/boot.ini && cat >> /mnt/boot.ini <<EOT
   9.143 +C:\\slitaz\\boot\\tazboot.exe="SliTaz"
   9.144 +EOT
   9.145 +	grep -qs menuitem /mnt/config.sys && !grep -q tazboot /mnt/config.sys &&
   9.146 +	sed -i 's/menudefault=/menuitem=slitaz,SliTaz\n&/' /mnt/config.sys &&
   9.147 +	cat >> /mnt/config.sys <<EOT
   9.148 +[slitaz]
   9.149 +device=\\slitaz\\boot\\tazboot.exe
   9.150 +EOT
   9.151 +}
   9.152 +
   9.153 +install()
   9.154 +{
   9.155 +	$DIALOG --clear \
   9.156 +		--title " SliTaz UMSDOS like installation " \
   9.157 +		--yes-label "Install" --yesno \
   9.158 +"\nSliTaz will be installed in the subdirectory \\slitaz of the current
   9.159 +DOS/Windows partition. You will see your files from /mnt/dos.\n\n
   9.160 +You will start SliTaz with \\slitaz\\boot\\tazboot.exe\n\n
   9.161 +To uninstall SliTaz, you have only to remove this directory.
   9.162 +The file \\boot.ini or \\config.sys may be modified too.\n\n
   9.163 +To do a traditionnal installation with disk partitioning
   9.164 +start SliTaz Live with 'SliTaz RAM boot' menu.\n
   9.165 +" 16 70
   9.166 +	[ $? -eq 0 -a -x /usr/sbin/mount.posixovl ] || return
   9.167 +	doinstall
   9.168 +	umount /proc
   9.169 +	exec chroot /mnt/slitaz /sbin/init
   9.170 +}
   9.171 +
   9.172 +tazboot()
   9.173 +{
   9.174 +	$DIALOG --clear \
   9.175 +		--title " SliTaz bootloader for DOS " \
   9.176 +		--yes-label "Install" --yesno \
   9.177 +"\nThe file TAZBOOT.EXE will be created in top directory. It supports
   9.178 +bzImage linux kernel, multiples initramfs, kernel command line and
   9.179 +ISO image file loopback (can retrieve files from an ISO file).\n\n
   9.180 +Usage: tazboot.exe [[@commands]|[kernel=<bzimage>] 
   9.181 +[initrd=<rootfs>[,<rootfs2>...]] [iso=<isofile>] cmdline args ...]\n\n
   9.182 +Defaults: tazboot @tazboot.cmd  or  tazboot kernel=bzImage auto\n\n\
   9.183 +Examples for tazboot.cmd:\n\n\
   9.184 +  iso=\\isos\\slitaz-4.0.iso\n\
   9.185 +  kernel=boot/bzImage\n\
   9.186 +  initrd=boot/rootfs4.gz,boot/rootfs3.gz,boot/rootfs2.gz,boot/rootfs1.gz\n\
   9.187 +  rw root=/dev/null autologin\n\n\
   9.188 +  kernel=\\slitaz\\vmlinuz root=/dev/sda5 ro\n\n
   9.189 +Unlike GRUB4DOS, it doesn't require unfragmented ISO image files.\n
   9.190 +" 24 78
   9.191 +	[ $? -eq 0 ] || return
   9.192 +	gettazboot /mnt/tazboot.exe
   9.193 +}
   9.194 +
   9.195 +text()
   9.196 +{
   9.197 +	umount -d /media/cdrom
   9.198 +	umount /mnt
   9.199 +	umount /proc
   9.200 +	exec /init
   9.201 +}
   9.202 +
   9.203 +live()
   9.204 +{
   9.205 +	n=0
   9.206 +	for i in $(ls -r /media/cdrom/boot/rootfs*); do
   9.207 +		[ $((n++)) -eq 0 ] || uncpio $i
   9.208 +	done
   9.209 +	text
   9.210 +}
   9.211 +
   9.212 +reboot()
   9.213 +{
   9.214 +	umount -d /media/cdrom
   9.215 +	umount /mnt
   9.216 +	/sbin/reboot -f
   9.217 +}
   9.218 +
   9.219 +poweroff()
   9.220 +{
   9.221 +	umount -d /media/cdrom
   9.222 +	umount /mnt
   9.223 +	/sbin/poweroff -f
   9.224 +}
   9.225 +
   9.226 +[ -x /usr/sbin/mount.posixovl ] ||
   9.227 +mv /usr/sbin/mount.posixovl.iso2exe /usr/sbin/mount.posixovl
   9.228 +mount -t proc /proc /proc
   9.229 +ISO="$(getarg iso | sed 's/.://;s|\\|/|g')"
   9.230 +getiso
   9.231 +case "$(basename $ISO | tr [A-Z] [a-z])$(getarg mode)" in
   9.232 +*install*)	install ;;
   9.233 +*live*)		live ;;
   9.234 +*text*)		text ;;
   9.235 +esac
   9.236 +
   9.237 +while true; do
   9.238 +	exec 3>&1
   9.239 +	value=`$DIALOG  --clear \
   9.240 +	--title " Welcome to SliTaz " \
   9.241 +	--menu "\nPlease select" 15 70 7 \
   9.242 +		"live"		"SliTaz RAM boot" \
   9.243 +		"text"		"SliTaz RAM boot (text mode only)" \
   9.244 +		"install"	"Hard disk installation" \
   9.245 +		"tazboot"	"Get tazboot.exe Linux loader" \
   9.246 +		"reboot"	"Restart the computer" \
   9.247 +		"poweroff"	"Power off" \
   9.248 +		"ash"		"Shell prompt" \
   9.249 +	2>&1 1>&3`
   9.250 +	retval=$?
   9.251 +	exec 3>&-
   9.252 +	[ $retval -eq 0 ] || continue
   9.253 +	$value
   9.254 +done
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/syslinux/stuff/iso2exe/iso2exe.sh	Thu Dec 13 14:33:27 2012 +0100
    10.3 @@ -0,0 +1,73 @@
    10.4 +#!/bin/sh
    10.5 +if [ "$1" == "--build" ]; then
    10.6 +	shift
    10.7 +	[ $(tar cf - $@ | wc -c) -gt $((32 * 1024)) ] &&
    10.8 +		echo "The file set $@ is too large (31K max) :" &&
    10.9 +		ls -l $@ && exit 1
   10.10 +	cat >> $0 <<EOM
   10.11 +$(tar cf - $@ | lzma e -si -so | uuencode -m -)
   10.12 +EOT
   10.13 +EOM
   10.14 +	sed -i '/--build/,/^fi/d' $0
   10.15 +	exit
   10.16 +fi
   10.17 +
   10.18 +ddq()
   10.19 +{
   10.20 +	dd $@ 2> /dev/null
   10.21 +}
   10.22 +
   10.23 +store()
   10.24 +{
   10.25 +	n=$2; for i in $(seq 8 8 ${4:-16}); do
   10.26 +		printf '\\\\x%02X' $(($n & 255))
   10.27 +		n=$(($n >> 8))
   10.28 +	done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
   10.29 +}
   10.30 +
   10.31 +main()
   10.32 +{
   10.33 +	case "$1" in
   10.34 +	--get)	shift
   10.35 +		uudecode | unlzma | tar xOf - $@
   10.36 +		exit ;;
   10.37 +	*)	cat > /dev/null
   10.38 +	esac
   10.39 +	
   10.40 +	[ ! -s "$1" ] && echo "usage: $0 image.iso" 1>&2 && exit 1
   10.41 +	case "$(od -N 2 -t x2 -An $1)" in
   10.42 +	*5a4d)	echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
   10.43 +	*0000)	[ -x /usr/bin/isohybrid ] && isohybrid $1
   10.44 +	esac
   10.45 +	[ ! -x /usr/sbin/mount.posixovl ] && 
   10.46 +	echo "No file mount.posixovl. Abort." 1>&2 && exit 1
   10.47 +		
   10.48 +	echo "Move syslinux hybrid boot record..."
   10.49 +	ddq if=$1 bs=512 count=1 | ddq of=$1 bs=512 count=1 seek=1 conv=notrunc 
   10.50 +	
   10.51 +	echo "Insert EXE boot record..."
   10.52 +	$0 --get bootiso.bin | ddq of=$1 conv=notrunc
   10.53 +
   10.54 +	# keep the largest room for the tazlito info file
   10.55 +	TMP=/tmp/iso2exe$$
   10.56 +	mkdir -p $TMP/usr/sbin
   10.57 +	cp /usr/sbin/mount.posixovl $TMP/usr/sbin/mount.posixovl.iso2exe
   10.58 +	$0 --get init > $TMP/init.exe
   10.59 +	chmod +x $TMP/init.exe $TMP/usr/sbin/mount.posixov*
   10.60 +	( cd $TMP ; ls init.exe usr/sbin/mount.posixov* | cpio -o -H newc ) | \
   10.61 +		lzma e $TMP/rootfs.gz -si 2> /dev/null
   10.62 +	SIZE=$(wc -c < $TMP/rootfs.gz)
   10.63 +	store 28 $SIZE $1
   10.64 +	OFS=$(( 0x8000 - $SIZE ))
   10.65 +	printf "Add rootfs.gz file at %04X...\n" $OFS
   10.66 +	cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
   10.67 +	rm -rf $TMP
   10.68 +	SIZE=$($0 --get lzcom.bin boot.com.lzma | wc -c)
   10.69 +	OFS=$(( $OFS - $SIZE ))
   10.70 +	printf "Add DOS boot file at %04X...\n" $OFS
   10.71 +	$0 --get lzcom.bin boot.com.lzma | ddq of=$1 bs=1 seek=$OFS conv=notrunc
   10.72 +	store 36 $(($OFS+0xE0)) $1
   10.73 +	store 30 ${RANDOM:-0} $1
   10.74 +}
   10.75 +
   10.76 +main $@ <<EOT
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/syslinux/stuff/iso2exe/iso9660.c	Thu Dec 13 14:33:27 2012 +0100
    11.3 @@ -0,0 +1,155 @@
    11.4 +#include <sys/types.h>
    11.5 +#include <fcntl.h>
    11.6 +#include <stdio.h>
    11.7 +#include "iso9660.h"
    11.8 +#define __ROCKRIDGE
    11.9 +
   11.10 +char *isofilename;
   11.11 +unsigned long isofileofs, isofilesize;
   11.12 +unsigned short isofilemod;
   11.13 +int isofd;
   11.14 +
   11.15 +#define SECTORSZ 2048
   11.16 +#define SECTORBITS 11
   11.17 +static char buffer[SECTORSZ];
   11.18 +
   11.19 +static int readsector(unsigned long offset)
   11.20 +{
   11.21 +	return (lseek(isofd, offset, SEEK_SET) != -1
   11.22 +		    && read(isofd, buffer, SECTORSZ) == SECTORSZ);
   11.23 +}
   11.24 +
   11.25 +int isoread(char *data, unsigned size)
   11.26 +{
   11.27 +	int get, n;
   11.28 +	
   11.29 +	if (size > isofilesize)
   11.30 +		size = isofilesize;
   11.31 +	if (lseek(isofd, isofileofs, SEEK_SET) == -1)
   11.32 +		return -1;
   11.33 +	for (get = size; get; get -= n, data += n) {
   11.34 +		n = read(isofd,data,get);
   11.35 +		if (n < 0)
   11.36 +			return n;
   11.37 +		if (n == 0)
   11.38 +			break;
   11.39 +		isofileofs += n;
   11.40 +		isofilesize -= n;
   11.41 +	}
   11.42 +	return size - get;
   11.43 +}
   11.44 +
   11.45 +static unsigned long isodirofs, isodirsize;
   11.46 +int isoreset(char *name)
   11.47 +{
   11.48 +	if (name)
   11.49 +		isofd = open(name, O_RDONLY);
   11.50 +	if (!readsector(16UL * 2048) || strncmp(buffer+1,"CD001",5))
   11.51 +		return -1;
   11.52 +	isodirofs = * (unsigned long *) (buffer + 0x9E);
   11.53 +	isodirofs <<= SECTORBITS;
   11.54 +	isodirsize = * (unsigned long *) (buffer + 0xA6);
   11.55 +	return 0;
   11.56 +}
   11.57 +
   11.58 +int isoreaddir(int restart)
   11.59 +{
   11.60 +	static unsigned long pos, dirofs, dirsize;
   11.61 +	static char dots[] = "..";
   11.62 +	int size, n;
   11.63 +#ifdef __ROCKRIDGE
   11.64 +	char *endname;
   11.65 +#endif
   11.66 +
   11.67 +	if (restart) {
   11.68 +		dirofs = isodirofs;
   11.69 +		dirsize = isodirsize;
   11.70 +		pos = SECTORSZ;
   11.71 +	}
   11.72 +	if (pos >= SECTORSZ) {
   11.73 +		if (dirsize < SECTORSZ) return -1;
   11.74 +		readsector(dirofs);
   11.75 +		dirofs += SECTORSZ;
   11.76 +		dirsize -= SECTORSZ;
   11.77 +		pos = 0;
   11.78 +	}
   11.79 +	size = * (short *) (buffer + pos);
   11.80 +	if (size == 0)
   11.81 +		return -1;
   11.82 +	isofileofs = (* (unsigned long *) (buffer + pos + 2)) << SECTORBITS;
   11.83 +	isofilesize = * (unsigned long *) (buffer + pos + 10);
   11.84 +	isofilemod = (buffer[pos + 25] & 2) ? 0040755 : 0100755;
   11.85 +#ifdef __ROCKRIDGE
   11.86 +	endname = NULL;
   11.87 +	n = (buffer[pos + 32] + pos + 34) & -2;
   11.88 +	do {
   11.89 +		int len = buffer[n + 2];
   11.90 +		switch (* (short *) (buffer + n)) {
   11.91 +		case 0x4D4E: // NM
   11.92 +			isofilename = buffer + n + 5;
   11.93 +			endname = buffer + n + len;
   11.94 +			break;
   11.95 +		case 0x5850: // PX
   11.96 +			isofilemod = * (short *) (buffer + n + 4);
   11.97 +			break;
   11.98 +		}
   11.99 +		n += len;
  11.100 +	}
  11.101 +	while (n + 2 < pos + size);
  11.102 +	if (endname)
  11.103 +		*endname = 0;
  11.104 +	else
  11.105 +#endif
  11.106 +	{
  11.107 +		isofilename = buffer + pos + 33;
  11.108 +		switch (* (short *) (isofilename - 1)) {
  11.109 +		case 0x0101:
  11.110 +			isofilename = dots;
  11.111 +			break;
  11.112 +		case 0x0001:
  11.113 +			isofilename = dots + 1;
  11.114 +			break;
  11.115 +		default:
  11.116 +			n = isofilename[-1];
  11.117 +			if (* (short *) (isofilename + n - 2) == 0x313B)
  11.118 +				n -= 2; // remove ;1
  11.119 +			if (isofilename[n - 1] == '.') n--;
  11.120 +			isofilename[n] = 0;
  11.121 +		}
  11.122 +	}
  11.123 +	pos += size;
  11.124 +	return 0;
  11.125 +}
  11.126 +
  11.127 +#define IS_DIR(x)( ((x) & ~0777) == 040000)
  11.128 +int isoopen(char *name)
  11.129 +{
  11.130 +	int restart;
  11.131 +	char *s, c;
  11.132 +
  11.133 +	while (*name == '/') {
  11.134 +		name++;
  11.135 +		isoreset(NULL);
  11.136 +	}
  11.137 +	s = name;
  11.138 +	while (1) {
  11.139 +		while (*s && *s != '/') s++;
  11.140 +		c = *s;
  11.141 +		*s = 0;
  11.142 +		for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
  11.143 +			if (strcmp(name, isofilename)) continue;
  11.144 +			if (IS_DIR(isofilemod)) {
  11.145 +				isodirofs = isofileofs;
  11.146 +				isodirsize = isofilesize;
  11.147 +				if (c) {
  11.148 +					*s++ = c;
  11.149 +					name = s;
  11.150 +					goto next;
  11.151 +				}
  11.152 +			}
  11.153 +			return 0;
  11.154 +		}
  11.155 +		return -1;
  11.156 +	  next: ;
  11.157 +	}
  11.158 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/syslinux/stuff/iso2exe/iso9660.h	Thu Dec 13 14:33:27 2012 +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/syslinux/stuff/iso2exe/libdos.c	Thu Dec 13 14:33:27 2012 +0100
    13.3 @@ -0,0 +1,130 @@
    13.4 +#include "libdos.h"
    13.5 +
    13.6 +char *progname(void)
    13.7 +{
    13.8 +#asm
    13.9 +		.bss
   13.10 +._name	lcomm	80
   13.11 +		.text
   13.12 +		push	es
   13.13 +		seg	cs
   13.14 +		mov	es, [0x2C]
   13.15 +		mov	cx, #-1
   13.16 +		xor	di, di
   13.17 +		xor	al, al
   13.18 +loop1:
   13.19 +		repne
   13.20 +		scasb
   13.21 +		scasb
   13.22 +		jne	loop1
   13.23 +		lea	si, [di+2]
   13.24 +		push	ds
   13.25 +		push	ds
   13.26 +		push	es
   13.27 +		pop	ds
   13.28 +		pop	es
   13.29 +		mov	di, ._name
   13.30 +		push	di
   13.31 +loop2:
   13.32 +		lodsb
   13.33 +		stosb
   13.34 +		or	al, al
   13.35 +		jnz	loop2
   13.36 +		pop	ax
   13.37 +		pop	ds
   13.38 +		pop	es
   13.39 +#endasm
   13.40 +}
   13.41 +
   13.42 +#ifdef __SLEEP
   13.43 +void sleep(int seconds)
   13.44 +{
   13.45 +	unsigned long n;
   13.46 +	
   13.47 +	n = (seconds * 182) / 10;
   13.48 +#asm
   13.49 +		push	es
   13.50 +		push	#0
   13.51 +		pop	es
   13.52 +		mov	di, #0x46C
   13.53 +sleeplp:	
   13.54 +		mov	cx, #0x8000
   13.55 +		or	dx, dx
   13.56 +		jne	siok
   13.57 +		mov	cx, ax
   13.58 +		jcxz	done
   13.59 +siok:
   13.60 +		sub	ax, cx
   13.61 +		sbb	dx, #0
   13.62 +		seg	es
   13.63 +		add	cx, [di]
   13.64 +zzz:
   13.65 +		seg	es
   13.66 +		cmp	cx, [di]
   13.67 +		jne	zzz
   13.68 +		jmp	sleeplp
   13.69 +done:
   13.70 +		pop	es
   13.71 +#endasm
   13.72 +}
   13.73 +#endif
   13.74 +
   13.75 +int chdirname(char *path)
   13.76 +{
   13.77 +#asm
   13.78 +		pop	ax
   13.79 +		pop	bx
   13.80 +		push	bx
   13.81 +		push	ax
   13.82 +		cmp	byte ptr [bx+1], #0x3A
   13.83 +		jne	nodisk
   13.84 +		mov	dl, [bx]
   13.85 +		or	dl, #0x20
   13.86 +		sub	dl, #0x61
   13.87 +		mov	ah, #0x0E
   13.88 +		push	bx
   13.89 +		int	0x21
   13.90 +		pop	bx
   13.91 +		inc	bx
   13.92 +		inc	bx
   13.93 +nodisk:
   13.94 +		mov	dx, bx
   13.95 +		xor	cx, cx
   13.96 +next:
   13.97 +		mov	al, [bx]
   13.98 +		cmp	al, #0x5C
   13.99 +		jne	tsteos
  13.100 +		mov	cx, bx
  13.101 +tsteos:
  13.102 +		inc	bx
  13.103 +		or	al, al
  13.104 +		jnz	next
  13.105 +		cbw
  13.106 +		jcxz	quit
  13.107 +		mov	bx, cx
  13.108 +		push	[bx]
  13.109 +		mov	[bx], al
  13.110 +		push	bx
  13.111 +		call	chdir
  13.112 +		pop	bx
  13.113 +		pop	[bx]
  13.114 +quit:
  13.115 +		ret
  13.116 +	
  13.117 +// int chdir(char *path)
  13.118 +_chdir:
  13.119 +		pop	ax
  13.120 +		pop	dx
  13.121 +		push	dx
  13.122 +		push	ax
  13.123 +chdir:
  13.124 +		stc
  13.125 +		mov	ax, #0x713B
  13.126 +		int	0x21
  13.127 +		jnc	chdireturn
  13.128 +		mov	ah, #0x3B
  13.129 +		int	0x21
  13.130 +chdireturn:
  13.131 +		sbb	ax, ax
  13.132 +#endasm
  13.133 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/syslinux/stuff/iso2exe/libdos.h	Thu Dec 13 14:33:27 2012 +0100
    14.3 @@ -0,0 +1,13 @@
    14.4 +#ifndef __LIBDOS_H
    14.5 +#define __LIBDOS_H
    14.6 +#undef  __SLEEP
    14.7 +# ifdef __MSDOS__
    14.8 +// extern void sleep(int seconds);
    14.9 +extern char *progname(void);
   14.10 +extern int chdir(char *path);
   14.11 +extern int chdirname(char *path);
   14.12 +# else
   14.13 +#define progname() argv[0]
   14.14 +#define chdirname(x) chdir(dirname(x))
   14.15 +# endif
   14.16 +#endif
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/syslinux/stuff/iso2exe/lzcom.S	Thu Dec 13 14:33:27 2012 +0100
    15.3 @@ -0,0 +1,36 @@
    15.4 +	.text
    15.5 +	.code16
    15.6 +	
    15.7 +ORGCOM	=	0x100
    15.8 +STKSZ	=	0x4000			// unlzma needs 16Kb
    15.9 +CODESZ	=	(0x10000-STKSZ)/2	//  max < 16 sectors = 32Kb
   15.10 +
   15.11 +	.org	0
   15.12 +
   15.13 +	.globl	_start
   15.14 +_start:
   15.15 +	cld
   15.16 +	movw	$packedcode-unpack, %ax
   15.17 +	movw	$packedcode+ORGCOM, %si
   15.18 +	movw	$-STKSZ-CODESZ, %di
   15.19 +	subw	%ax, %di
   15.20 +	pushw	%di
   15.21 +	movw	$CODESZ/2, %cx
   15.22 +	rep
   15.23 +	  movsw				// packed code
   15.24 +	movw	$unpack+ORGCOM, %si
   15.25 +	movw	%di, %bx
   15.26 +	xchgw	%ax, %cx
   15.27 +	rep
   15.28 +	  movsb				// decompressor
   15.29 +	movw	$ORGCOM, %di
   15.30 +	popw	%si
   15.31 +	pushw	%di
   15.32 +	pushw	%bx
   15.33 +	ret
   15.34 +
   15.35 +unpack:
   15.36 +#define FLAT16
   15.37 +#include "unlzma.S"
   15.38 +
   15.39 +packedcode:
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/syslinux/stuff/iso2exe/unlzma.S	Thu Dec 13 14:33:27 2012 +0100
    16.3 @@ -0,0 +1,826 @@
    16.4 +// #define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
    16.5 +//
    16.6 +// #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
    16.7 +// #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
    16.8 +// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
    16.9 +//
   16.10 +//#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
   16.11 +//  { UpdateBit0(p); mi <<= 1; A0; } else \
   16.12 +//  { UpdateBit1(p); mi = (mi + mi) + 1; A1; }
   16.13 +//
   16.14 +// #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
   16.15 +//
   16.16 +// #define RangeDecoderBitTreeDecode(probs, numLevels, res) \
   16.17 +//  { int i = numLevels; res = 1; \
   16.18 +//  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
   16.19 +//  res -= (1 << numLevels); }
   16.20 +/*
   16.21 + * Compression with : lzma e src dst -eos -pb2 -lp0 -lc3
   16.22 + */
   16.23 +
   16.24 +#define PROP_PB 2
   16.25 +#define PROP_LP 0
   16.26 +#define PROP_LC 3
   16.27 +#define PROPS (PROP_LC+(PROP_LP*9)+(PROP_PB*45))
   16.28 +
   16.29 +// static const Byte *Buffer;
   16.30 +// static UInt32 bound, Code, Range;
   16.31 +
   16.32 +/*
   16.33 + * Buffer register DS:SI
   16.34 + * all var based ws=ss:bp
   16.35 + */
   16.36 +
   16.37 +rep0		=	-4		// long
   16.38 +rep1		=	rep0-4		// long
   16.39 +rep2		=	rep0-8		// long
   16.40 +rep3		=	rep0-12		// long
   16.41 +state		=	-17		// byte, 0..11
   16.42 +posState 	=	state-1		// byte, 0..15
   16.43 +posState2 	=	posState-1	// byte, 0..15
   16.44 +scratched	=	rep0-16		// byte = 1
   16.45 +Code		=	-24		// long
   16.46 +outStream	=	-28		// long
   16.47 +nowPos		=	outStream	// long
   16.48 +Range		=	Code-8		// long
   16.49 +#define LOCALS		32
   16.50 +
   16.51 +// int LzmaDecode(CLzmaDecoderState *vs,
   16.52 +//     const unsigned char *inStream, 
   16.53 +//     unsigned char *outStream)
   16.54 +// {
   16.55 +//   CProb *p = vs->Probs;
   16.56 +//   SizeT nowPos = 0;
   16.57 +//   #define posStateMask = (1 << (vs->Properties.pb)) - 1;
   16.58 +//   #define literalPosMask = (1 << (vs->Properties.lp)) - 1;
   16.59 +//   int lc = vs->Properties.lc, state = 0, len = 0;
   16.60 +//   UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
   16.61 +// 
   16.62 +//   {
   16.63 +//     UInt32 i, numProbs = Literal /*1846*/
   16.64 +// 	    + ((UInt32)LZMA_LIT_SIZE /*768*/ << (lc + vs->Properties.lp));
   16.65 +//     for (i = 0; i < numProbs; i++) p[i] = kBitModelTotal /*2048*/ >> 1;
   16.66 +
   16.67 +#define WS (1846+(768<<(PROP_LC+PROP_LP)))
   16.68 +#if (WS+WS+LOCALS) >= 65000
   16.69 +/* MAX WS = (1846+(768<<(8+4))) > 3MB! */
   16.70 +#error invalid (lc,lp,pb) : out of memory
   16.71 +#endif
   16.72 +
   16.73 +ws1	=	WS
   16.74 +ws2	=	ws1*2
   16.75 +ws	=	ws2+LOCALS+15
   16.76 +
   16.77 +#ifndef FLAT16
   16.78 +#define INC	incl
   16.79 +#else
   16.80 +#define INC	incw
   16.81 +#endif
   16.82 +#ifndef FLAT32
   16.83 +#define	AX	%ax
   16.84 +#define	BX	%bx
   16.85 +#define	CX	%cx
   16.86 +#define	DX	%dx
   16.87 +#define	SI	%si
   16.88 +#define	DI	%di
   16.89 +#define	BP	%bp
   16.90 +#define	SP	%sp
   16.91 +#define CWD	cwd
   16.92 +#else
   16.93 +#define	AX	%eax
   16.94 +#define	BX	%ebx
   16.95 +#define	CX	%ecx
   16.96 +#define	DX	%edx
   16.97 +#define	SI	%esi
   16.98 +#define	DI	%edi
   16.99 +#define	BP	%ebp
  16.100 +#define	SP	%esp
  16.101 +#define CWD	cdq
  16.102 +#endif
  16.103 +/*
  16.104 + * LzmaDecode:
  16.105 +#ifndef FLAT32
  16.106 + *   input   ds:si=inStream, es:di=outStream
  16.107 + *   output  outStream[], ds:si, es:di
  16.108 + 	.code 16
  16.109 +#else
  16.110 + *   input   esi=inStream, edi=outStream
  16.111 + *   output  outStream[], esi, edi
  16.112 + 	.code 32
  16.113 +#endif
  16.114 + */
  16.115 + 
  16.116 +	mov	$ws1, CX
  16.117 +lzd1:
  16.118 +	pushw	$2048/2
  16.119 +	loop	lzd1
  16.120 +	mov	SP, BP
  16.121 +	movb	$((LOCALS+3)/4)*2, %cl
  16.122 +initlocals:
  16.123 +	pushl	$1
  16.124 +	loop	initlocals
  16.125 +
  16.126 +#if !defined(FLAT32) && !defined(FLAT16)
  16.127 +	movb	$4, %cl
  16.128 +	movw	%es, %bx
  16.129 +	shrw	%cl, %bx
  16.130 +	movw	%es, %dx
  16.131 +	shlw	%cl, %dx
  16.132 +	addw	%dx, %di
  16.133 +	movw	%di, outStream(%bp)
  16.134 +	adcb	%bh, outStream+2(%bp)
  16.135 +	incw	%cx
  16.136 +#else
  16.137 +	movb	$5, %cl
  16.138 +	mov	DI, outStream(BP)
  16.139 +#endif
  16.140 +
  16.141 +//   Byte previousByte = 0;
  16.142 +	xor	BX, BX
  16.143 +
  16.144 +// #define RC_INIT(buffer) 
  16.145 +//    Buffer = buffer; Code = 0; Range = 0xFFFFFFFF; 
  16.146 +//    { int i; for(i=0; i<5; i++) { Code = (Code<<8) | RC_READ_BYTE; }}
  16.147 +//   }
  16.148 +//   RC_INIT(inStream);
  16.149 +
  16.150 +	add	$13, SI		// skip header
  16.151 +setrep:
  16.152 +	call	RC_LOAD_BYTE
  16.153 +	decb	Range(BP)
  16.154 +	loop	setrep
  16.155 +
  16.156 +lzdmainlp:
  16.157 +//   while(1) {
  16.158 +//     CProb *prob;
  16.159 +//     int posState = (int)((nowPos) & posStateMask);
  16.160 +// 
  16.161 +//     prob = p + IsMatch /*0*/ + (state << kNumPosBitsMax /*4*/) + posState;
  16.162 +//     if (Bit0(prob)) { /* char */
  16.163 +
  16.164 +	xor	DX, DX
  16.165 +	call	Bit1state	// Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
  16.166 +	mov	$state, DI
  16.167 +	jc	lzdstring
  16.168 +
  16.169 +//       prob = p + Literal /*1846*/ + (LZMA_LIT_SIZE /*768*/ * 
  16.170 +// 	((((nowPos) & literalPosMask) << lc) + (previousByte >> (8 - lc))));
  16.171 +
  16.172 +#if PROP_LC != 0
  16.173 +	shrb	$8-PROP_LC, %bl
  16.174 +#endif
  16.175 +
  16.176 +#if PROP_LP != 0
  16.177 +	movb	posState2(BP), %dl
  16.178 +	shl	$PROP_LC, DX
  16.179 +	movb	$0, %bh
  16.180 +	add	BX, DX
  16.181 +#endif
  16.182 +
  16.183 +	movb	$3, %ah
  16.184 +	mul	BX		// dx = 3*bh
  16.185 +	add	$1846, AX
  16.186 +
  16.187 +//       int symbol = 1;
  16.188 +
  16.189 +	CWD
  16.190 +	inc	DX		// symbol = 1
  16.191 +	xchg	AX, CX		// save prob
  16.192 +
  16.193 +//       if (state >= kNumLitStates /*7*/) { /* previous was string */
  16.194 +//       if (state < 4) state = 0;
  16.195 +
  16.196 +lzd6z:
  16.197 +	subb	$3, (BP, DI)
  16.198 +
  16.199 +//       if (state < 4) state = 0;
  16.200 +
  16.201 +	jnc	lzd6
  16.202 +	movb	%dh, (BP, DI)	// %dh = 0
  16.203 +
  16.204 +lzd6:
  16.205 +//       else if (state < 10) state -= 3;
  16.206 +
  16.207 +	cmpb	$10-3, (BP, DI)
  16.208 +	
  16.209 +//       else state -= 6;
  16.210 +
  16.211 +	jnb	lzd6z
  16.212 +	cmpb	$7-3-1, (BP, DI)
  16.213 +	jbe	lzd3
  16.214 +	
  16.215 +//         int matchByte = outStream[nowPos - rep0];
  16.216 +
  16.217 +	call	DicoRep02ESDI	// %bl = outStream[nowPos - rep0];
  16.218 +	
  16.219 +//         do {
  16.220 +//           int bit;
  16.221 +//           CProb *probLit;
  16.222 +//           matchByte <<= 1; bit = (matchByte & 0x100);
  16.223 +
  16.224 +	movb	$1, %bh
  16.225 +lzd4:
  16.226 +	shlb	$1, %bl			// matchByte <<= 1
  16.227 +	sbb	DI, DI			// save bit=C
  16.228 +
  16.229 +//           probLit = prob + 0x100 + bit + symbol;
  16.230 +
  16.231 +	mov	CX, AX			// restore prob
  16.232 +	adcb	%bh, %ah		// + bit + 0x100
  16.233 +	
  16.234 +//           RC_GET_BIT2(probLit, symbol, if (bit) break, if (!bit) break)
  16.235 +
  16.236 +	call	Bit1axdx		// C,%ax = Bit1(prob+%ax)
  16.237 +	rclb	$1, %dl			// symbol <<= 1; symbol |= C
  16.238 +	jc	lzd5			// if symbol >= 0x100
  16.239 +	cmp	DI, AX
  16.240 +	jz	lzd4			// if bit == Bit1(prob+%ax)
  16.241 +
  16.242 +//         } while (symbol < 0x100);
  16.243 +//       }
  16.244 +lzd3:
  16.245 +//       while (symbol < 0x100) {
  16.246 +//         CProb *probLit = prob + symbol;
  16.247 +//         RC_GET_BIT(probLit, symbol)
  16.248 +//       }
  16.249 +
  16.250 +	xor	BX, BX
  16.251 +	jmp	lzd4
  16.252 +lzd5:
  16.253 +
  16.254 +//       outStream[nowPos++] = previousByte = (Byte)symbol;
  16.255 +
  16.256 +	xchg	AX, DX
  16.257 +	call	outchar		// %bl = outStream[nowPos++] = %al;
  16.258 +	jmp	lzdmainlp
  16.259 +
  16.260 +//     }
  16.261 +
  16.262 +lzdstring:
  16.263 +	mov	$1, CX
  16.264 +
  16.265 +//     else { /* string */
  16.266 +//       prob = p + IsRep /*192*/ + state;
  16.267 +
  16.268 +	movb	$192, %dl
  16.269 +	addb	(BP, DI), %dl
  16.270 +	mov	$rep0, DI
  16.271 +
  16.272 +//       if (Bit0(prob)) {
  16.273 +
  16.274 +	call	Bit1dx		// Bit1(prob)
  16.275 + 	jc	lzd8
  16.276 +
  16.277 +//         rep3 = rep2; rep2 = rep1; rep1 = rep0;
  16.278 +//         state = (state < kNumLitStates /*7*/) ? 0 : 3;
  16.279 +
  16.280 +	stc
  16.281 +
  16.282 +//         prob = p + LenCoder /*818*/;
  16.283 +
  16.284 +	mov	$818, DX
  16.285 +
  16.286 +//       }
  16.287 +
  16.288 +	jmp	lzd11a
  16.289 +
  16.290 +//       else {
  16.291 +lzd8:
  16.292 +//         prob += kNumStates /*12*/;
  16.293 +//         if (Bit0(prob)) {
  16.294 +	call	Bit1dx12	// prob += 12; Bit1(prob)
  16.295 +	jc	lzd11
  16.296 +//           prob = p + IsRep0Long /*240*/ + (state << kNumPosBitsMax /*4*/) 
  16.297 +// 		   + posState;
  16.298 +	movb	$240, %dl	// dh=0
  16.299 +
  16.300 +//           if (Bit0(prob)) {
  16.301 +
  16.302 +	call	Bit1state	// Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
  16.303 +	jc	lzd12
  16.304 +
  16.305 +//             // if (nowPos == 0) return LZMA_RESULT_DATA_ERROR;
  16.306 +//             state = (state < kNumLitStates /*7*/) ? 9 : 11;
  16.307 +
  16.308 +	movb	$9, %dl
  16.309 +
  16.310 +//             len++; goto string;
  16.311 +	jmp	lzd13string	// ax = 0
  16.312 +//           }
  16.313 +//         }
  16.314 +//         else {
  16.315 +lzd11:
  16.316 +//           UInt32 distance = rep1;
  16.317 +//           prob += kNumStates /*12*/;
  16.318 +//           if (!Bit0(prob)) {
  16.319 +
  16.320 +	call	Bit1dx12	// prob += 12; Bit1(prob)
  16.321 +	jnc	lzd11z
  16.322 +
  16.323 +//             prob += kNumStates /*12*/;
  16.324 +//             if (Bit0(prob)) distance = rep2;
  16.325 +
  16.326 +	call	Bit1dx12	// prob += 12; Bit1(prob)
  16.327 +lzd11a:
  16.328 +	adcb	%cl, %cl
  16.329 +	
  16.330 +//             else { distance = rep3; rep3 = rep2; }
  16.331 +//             rep2 = rep1;
  16.332 +//           }
  16.333 +//           rep1 = rep0; rep0 = distance;
  16.334 +
  16.335 +lzd11z:
  16.336 +	shl	$2, CX		// 8->32 bits
  16.337 +	sub	CX, DI		// &rep[cx]
  16.338 +	movl	(BP, DI), %eax
  16.339 +rotreplp:
  16.340 +	movb	4(BP, DI), %bl
  16.341 +	movb	%bl, (BP, DI)
  16.342 +	inc	DI
  16.343 +	loop	rotreplp
  16.344 +	testb	%dh, %dh
  16.345 +	jnz	lzd10
  16.346 +	movl	%eax, (BP, DI)
  16.347 +
  16.348 +//         }
  16.349 +lzd12:
  16.350 +//         state = (state < kNumLitStates /*7*/) ? 8 : 11;
  16.351 +
  16.352 +	movb	$0x08, %cl
  16.353 +
  16.354 +//         prob = p + RepLenCoder /*1332*/;
  16.355 +
  16.356 +	mov	$1332, DX
  16.357 +
  16.358 +//       }
  16.359 +lzd10:
  16.360 +	push	CX		// CX = 0
  16.361 +
  16.362 +//       { /* get len */
  16.363 +//         int numBits, offset;
  16.364 +//         CProb *probLen = prob + LenChoice /*0*/;
  16.365 +//         numBits = kLenNumLowBits /*3*/;
  16.366 +
  16.367 +	movb	$8, %cl		// numBits : 3,3,8
  16.368 +
  16.369 +//         if (Bit0(probLen)) {
  16.370 +
  16.371 +	call	Bit1dx		// Bit1(prob)
  16.372 +	xchg	AX, BX
  16.373 +	inc	DX
  16.374 +	jnc	lzd15		// bx=0
  16.375 +
  16.376 +//           probLen = prob + LenLow/*2*/ + (posState << kLenNumLowBits/*3*/);
  16.377 +//           offset = 0;
  16.378 +//         }
  16.379 +//         else {
  16.380 +//           probLen = prob + LenChoice2 /*1*/;
  16.381 +
  16.382 +	call	Bit1dx		// Bit1(prob)
  16.383 +	add	AX, BX
  16.384 +
  16.385 +#if PROP_PB != 0
  16.386 +	inc	AX		// ah=0
  16.387 +#endif
  16.388 +	jc	lzd16		// %ax=0, %bx=-2 
  16.389 +lzd15:
  16.390 +#if PROP_PB != 0
  16.391 +	movb	$8, %al
  16.392 +	mulb	posState(BP)
  16.393 +#endif
  16.394 +
  16.395 +//           if (Bit0(probLen)) {
  16.396 +//             probLen = prob + LenMid/*130*/ + (posState << kLenNumMidBits/*3*/);
  16.397 +
  16.398 +	movb	$3, %cl		// numBits : 3,3,8
  16.399 +lzd16:
  16.400 +#if PROP_PB != 0
  16.401 +	add	$2-128-1, AX	// probLen : 2,130,258
  16.402 +#else
  16.403 +	mov	$2-128-1, AX	// probLen : 2,130,258
  16.404 +#endif
  16.405 +	add	DX, AX
  16.406 +	mov	$-8+1, DX	// offset  : 0,8,16
  16.407 +lzdargslp:
  16.408 +	add	$8, DX
  16.409 +	add	$128, AX
  16.410 +	inc	BX
  16.411 +	jle	lzdargslp	// leave with bx=1
  16.412 +
  16.413 +//             offset = kLenNumLowSymbols /*8*/;
  16.414 +//             //numBits = kLenNumMidBits /*3*/;
  16.415 +//           }
  16.416 +//           else {
  16.417 +//             probLen = prob + LenHigh /*258*/;
  16.418 +//             offset = kLenNumLowSymbols /*8*/ + kLenNumMidSymbols /*8*/;
  16.419 +//             numBits = kLenNumHighBits /*8*/;
  16.420 +//           }
  16.421 +//         }
  16.422 +//         RangeDecoderBitTreeDecode(probLen, numBits, len); len += offset;
  16.423 +
  16.424 +	push	DX
  16.425 +	call	RangeDecoder	// %ax=probs, %cx=numLevels, %ax=res
  16.426 +	pop	DX
  16.427 +	add	DX, AX		// offset
  16.428 +	pop	DX		// 0
  16.429 +lzd13string:
  16.430 +	push	AX
  16.431 +
  16.432 +// state = (state < kNumLitStates /*7*/) ? dl : dl|3;
  16.433 +
  16.434 +	movb	$7, %cl
  16.435 +	cmpb	%cl, state(BP)
  16.436 +	jb	new_state
  16.437 +	orb	$3, %dl
  16.438 +new_state:
  16.439 +	movb	%dl, state(BP)
  16.440 +
  16.441 +//       } /* get len */
  16.442 +//       if (state < 4) {
  16.443 +
  16.444 +	cmpb	$4-1, %dl
  16.445 +	ja	lzd19
  16.446 +
  16.447 +//         int posSlot;
  16.448 +//         state += kNumLitStates /*7*/;
  16.449 +
  16.450 +	addb	%cl, state(BP)
  16.451 +
  16.452 +//         prob = p + PosSlot /*432*/ + (((len < kNumLenToPosStates /*4*/) ? 
  16.453 +// 		len : kNumLenToPosStates - 1) << kNumPosSlotBits /*6*/);
  16.454 +
  16.455 +	cmp	$4+1, AX
  16.456 +	jb	lzd21
  16.457 +	mov	$3+1, AX
  16.458 +
  16.459 +lzd21:
  16.460 +
  16.461 +	dec	CX		// cx = 6
  16.462 +	shl	%cl, AX
  16.463 +	add	$432-64, AX
  16.464 +
  16.465 +//         RangeDecoderBitTreeDecode(prob, kNumPosSlotBits /*6*/, posSlot);
  16.466 +
  16.467 +	call	RangeDecoder	// %ax=probs, %cx=numLevels, %ax=res
  16.468 +
  16.469 +//         if (posSlot >= kStartPosModelIndex /*4*/) {
  16.470 +//           int numDirectBits = ((posSlot >> 1) - 1);
  16.471 +
  16.472 +#ifndef FLAT32
  16.473 +	movw	%cx, 2(%bp, %di)	// %cx = 0
  16.474 +#endif
  16.475 +	mov	AX, (BP, DI)
  16.476 +	mov	AX, CX
  16.477 +	shrw	$1, CX
  16.478 +	dec	CX
  16.479 +	cmpb	$4, %al
  16.480 +	jb	lzd22
  16.481 +
  16.482 +//           rep0 = (2 | ((UInt32)posSlot & 1));
  16.483 +
  16.484 +	andb	%bl, (BP, DI)		// %bx=1
  16.485 +	orb	$2, (BP, DI)
  16.486 +
  16.487 +//           if (posSlot < kEndPosModelIndex /*14*/) {
  16.488 +
  16.489 +	cmpb	$14, %al
  16.490 +	jnb	lzd23
  16.491 +
  16.492 +//             rep0 <<= numDirectBits;
  16.493 +
  16.494 +	neg	AX
  16.495 +	shll	%cl, (BP, DI)
  16.496 +	add	(BP, DI), AX
  16.497 +
  16.498 +//             prob = p + SpecPos /*688*/ + rep0 - posSlot - 1;
  16.499 +
  16.500 +	add	$687, AX
  16.501 +	jmp	lzd24
  16.502 +
  16.503 +//           }
  16.504 +//           else {
  16.505 +lzd23:
  16.506 +//             numDirectBits -= kNumAlignBits /*4*/;
  16.507 +//             do {
  16.508 +//               RC_NORMALIZE; Range >>= 1; rep0 <<= 1;
  16.509 +//               if (Code >= Range) { Code -= Range; rep0 |= 1; }
  16.510 +
  16.511 +lzd23z:
  16.512 +	call	RC_NORMALIZE
  16.513 +	shrl	$1, Range(BP)
  16.514 +	movl	Range(BP), %eax
  16.515 +	cmpl	Code(BP), %eax
  16.516 +	ja	lzd25
  16.517 +	subl	%eax, Code(BP)
  16.518 +	stc
  16.519 +lzd25:
  16.520 +	rcll	$1, (BP, DI)
  16.521 +
  16.522 +//             } while (--numDirectBits != 0);
  16.523 +
  16.524 +	cmpb	$4+1, %cl
  16.525 +	loopne	lzd23z
  16.526 +
  16.527 +//             prob = p + Align /* 802 */; numDirectBits = kNumAlignBits /*4*/;
  16.528 +//             rep0 <<= numDirectBits;
  16.529 +
  16.530 +	shll	%cl, (BP, DI)
  16.531 +	mov	$802, AX
  16.532 +//           }
  16.533 +
  16.534 +lzd24:
  16.535 +	call	RangeDecoder	// %ax=probs, %cx=numLevels, %ax=res
  16.536 +
  16.537 +//           {
  16.538 +//             int i = 1, mi = 1;
  16.539 +//             do {
  16.540 +//               CProb *prob3 = prob + mi;
  16.541 +//               RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
  16.542 +
  16.543 +	orb	%dh, (BP, DI)	// update rep0 with DirectBits
  16.544 +
  16.545 +//               i <<= 1;
  16.546 +//             } while(--numDirectBits != 0);
  16.547 +//           }
  16.548 +//         } else rep0 = posSlot;
  16.549 +lzd22:
  16.550 +//         if (++rep0 == (UInt32)(0)) break; /* EOF */
  16.551 +
  16.552 +	incl	(BP, DI)
  16.553 +
  16.554 +lzd19:
  16.555 +	pop	CX
  16.556 +	jz	lzdone
  16.557 +
  16.558 +//       }
  16.559 +//       len += kMatchMinLen;/*2*/
  16.560 +
  16.561 +	inc	CX
  16.562 +
  16.563 +//     string: // if (rep0 > nowPos) return LZMA_RESULT_DATA_ERROR;
  16.564 +//       do {
  16.565 +lzd13z:
  16.566 +//         previousByte = outStream[nowPos - rep0];
  16.567 +//         outStream[nowPos++] = previousByte;
  16.568 +
  16.569 +	call	outcharDico 	// %bl = outStream[nowPos++] = outStream[nowPos - rep0]
  16.570 +
  16.571 +//       } while(--len != 0);
  16.572 +
  16.573 +	loop	lzd13z
  16.574 +
  16.575 +//     } /* char/string */
  16.576 +//   }
  16.577 +
  16.578 +	jmp	lzdmainlp
  16.579 +
  16.580 +lzdone:
  16.581 +//   //RC_NORMALIZE;
  16.582 +//   //*inSizeProcessed = (SizeT)(Buffer - inStream); *outSizeProcessed = nowPos;
  16.583 +//   return LZMA_RESULT_OK;
  16.584 +	call	Dico2ESDI	// set es & di (rep0 = 0)
  16.585 +	lea	ws2(BP), SP	// dealloc
  16.586 +	ret	
  16.587 +// }
  16.588 +
  16.589 +// al = outStream[nowPos - rep0];
  16.590 +
  16.591 +/*
  16.592 + * output  es:di, al
  16.593 + * scratch bh, cl, flags
  16.594 + */
  16.595 +
  16.596 +DicoRep02ESDI:
  16.597 +	stc
  16.598 +
  16.599 +// bl = outStream[nowPos];
  16.600 +
  16.601 +/*
  16.602 + * output  es:di, bl
  16.603 + * scratch bh, cl, flags
  16.604 + */
  16.605 + 
  16.606 +Dico2ESDI:
  16.607 +#if !defined(FLAT32) && !defined(FLAT16)
  16.608 +	movl	nowPos(%bp), %ebx
  16.609 +	jnc	Dico2ESDIz
  16.610 +	subl	rep0(%bp), %ebx
  16.611 +Dico2ESDIz:
  16.612 +	movw	%bx, %di
  16.613 +	xorw	%bx, %bx
  16.614 +	shrl	$4, %ebx
  16.615 +	movw	%bx, %es
  16.616 +	movb	%es:(%di), %bl
  16.617 +#else
  16.618 +	mov	nowPos(BP), DI
  16.619 +	jnc	Dico2ESDIz
  16.620 +	sub	rep0(BP), DI
  16.621 +Dico2ESDIz:
  16.622 +	movb	(DI), %bl
  16.623 +#endif
  16.624 +	ret
  16.625 +
  16.626 +outcharDico:
  16.627 +
  16.628 +// bl = outStream[nowPos++] = outStream[nowPos - rep0]
  16.629 +
  16.630 +/*
  16.631 + * output  es:di, bl
  16.632 + * update  nowPos
  16.633 + * scratch ax, dx, bh, cl, flags
  16.634 + */
  16.635 +
  16.636 +	call	DicoRep02ESDI	// %bl = outStream[nowPos - rep0]
  16.637 +	xchg	AX, BX
  16.638 +outchar:
  16.639 +
  16.640 +// bl = outStream[nowPos++] = previousByte = al;
  16.641 +
  16.642 +/*
  16.643 + * output  bl
  16.644 + * update  nowPos
  16.645 + * scratch ax, dx, bh, di, cl, flags
  16.646 + */
  16.647 +
  16.648 +	clc
  16.649 +	call	Dico2ESDI
  16.650 +	stosb
  16.651 +	xchg	AX, BX		// previous byte
  16.652 +
  16.653 +//	int posState = (int)((nowPos) & posStateMask);
  16.654 +
  16.655 +#if PROP_PB != 0 && PROP_LP != 0
  16.656 +	addw	$0x0101, posState2(BP)
  16.657 +	andb	$(((1 << PROP_PB) -1)<<8)+((1 << PROP_LP) -1), posState2(BP)
  16.658 +#else
  16.659 +# if PROP_PB != 0
  16.660 +	incb	posState(BP)
  16.661 +	andb	$((1 << PROP_PB) -1), posState(BP)
  16.662 +# endif
  16.663 +# if PROP_LP != 0
  16.664 +	incb	posState2(BP)
  16.665 +	andb	$((1 << PROP_LP) -1), posState2(BP)
  16.666 +# endif
  16.667 +#endif
  16.668 +	INC	nowPos(BP)
  16.669 +	ret
  16.670 +
  16.671 +//  
  16.672 +// #define RC_NORMALIZE if (Range < kTopValue) 
  16.673 +//    { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
  16.674 +
  16.675 +/*
  16.676 + * update  Range, Code, ds:si
  16.677 + * scratch flags
  16.678 + */
  16.679 +
  16.680 +RC_NORMALIZE:
  16.681 +	cmpb	$0, Range+3(BP)
  16.682 +	jne	RC_NORMALIZE_1
  16.683 +RC_LOAD_BYTE:
  16.684 +	push	AX
  16.685 +	shll	$8, Range(BP)
  16.686 +	shll	$8, Code(BP)
  16.687 +#if !defined(FLAT32) && !defined(FLAT16)
  16.688 +	testw	%si, %si
  16.689 +	jns	RC_READ_BYTE
  16.690 +	movw	%ds, %ax
  16.691 +	incw	%ax
  16.692 +	movw	%ax, %ds
  16.693 +	addw	$-16, %si
  16.694 +RC_READ_BYTE:
  16.695 +#endif
  16.696 +	lodsb
  16.697 +	movb	%al, Code(BP)
  16.698 +	pop	AX
  16.699 +RC_NORMALIZE_1:
  16.700 +	ret
  16.701 +
  16.702 +// Bit1(dx + (state << kNumPosBitsMax /*4*/) + posState)
  16.703 +
  16.704 +Bit1state:
  16.705 +	movb	$16, %al
  16.706 +	mulb	state(BP)
  16.707 +# if PROP_PB != 0
  16.708 +	addb	posState(BP), %al
  16.709 +# endif
  16.710 +Bit1axdx:
  16.711 +	add	DX, AX
  16.712 +	jmp	Bit1
  16.713 +
  16.714 +// prob += 12; Bit1(prob)
  16.715 +
  16.716 +Bit1dx12:
  16.717 +	add	$12, DX
  16.718 +Bit1dx:
  16.719 +	mov	DX, AX
  16.720 +
  16.721 +// static int Bit1(CProb *p)
  16.722 +
  16.723 +Bit1:
  16.724 +/*
  16.725 + * input   ax=p
  16.726 + * output  C, ax
  16.727 + * update  bound, Range, Code, ds:si
  16.728 + * scratch flags
  16.729 + */
  16.730 + 
  16.731 +// {
  16.732 +// 	RC_NORMALIZE;
  16.733 +
  16.734 +	call  RC_NORMALIZE		// kill %ax, update %si
  16.735 +
  16.736 +	pushal
  16.737 +
  16.738 +	xchg	AX, DI
  16.739 +	add	DI, DI			// short *
  16.740 +	
  16.741 +
  16.742 +// 	bound = (Range>>kNumBitModelTotalBits /*11*/) * *(p);
  16.743 +
  16.744 +	movl	Range(BP), %eax
  16.745 +	shrl	$11, %eax
  16.746 +	movzwl	(BP, DI), %edx
  16.747 +	mull	%edx
  16.748 +
  16.749 +// 	if (Code < bound) {
  16.750 +
  16.751 +	cmpl	Code(BP), %eax
  16.752 +	jbe	Bit1_1
  16.753 +
  16.754 +//    		Range = bound;
  16.755 +
  16.756 +	movl	%eax, Range(BP)
  16.757 +
  16.758 +// 		*(p) += (kBitModelTotal /*2048*/ - *(p)) >> kNumMoveBits /*5*/;
  16.759 +
  16.760 +	movw	$2048, %ax
  16.761 +
  16.762 +// 		return 0;
  16.763 +
  16.764 +	jmp	Bit1_2
  16.765 +
  16.766 +//	}
  16.767 +// 	else {
  16.768 +
  16.769 +Bit1_1:
  16.770 +
  16.771 +//    		Range -= bound; Code -= bound;
  16.772 +
  16.773 +	subl	%eax, Range(BP)
  16.774 +	subl	%eax, Code(BP)
  16.775 +
  16.776 +// 		*(p) -= (*(p)) >> kNumMoveBits /*5*/;
  16.777 +
  16.778 +	movw	$31, %ax
  16.779 +
  16.780 +// 		return 1;
  16.781 +
  16.782 +	stc
  16.783 +Bit1_2:
  16.784 +	pushf
  16.785 +	subw	(BP, DI), %ax
  16.786 +	sarw	$5, %ax
  16.787 +	addw	%ax, (BP, DI)
  16.788 +	popf
  16.789 +	popal
  16.790 +	sbb	AX, AX
  16.791 +
  16.792 +// 	}
  16.793 +// }
  16.794 +
  16.795 +	ret
  16.796 +
  16.797 +RangeDecoder:
  16.798 +
  16.799 +/*
  16.800 + * input   ax=probs cx=numLevels (< 8) bx=1
  16.801 + * output  ax=res (backward), dh (forward)
  16.802 + * update  bound, Range, Code, ds:si
  16.803 + * scratch flags, cx=0, dl
  16.804 + */
  16.805 + 
  16.806 +	push	BX
  16.807 +	
  16.808 +//   { int i = numLevels; res = 1; 
  16.809 +	mov	BX, DX		// res = 1
  16.810 +	
  16.811 +//   do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); 
  16.812 +
  16.813 +RangeDecoder_1:
  16.814 +	push	AX
  16.815 +	call	Bit1axdx		// C,%ax = Bit1(prob+%ax)
  16.816 +	rclb	$1, %dl			// res <<= 1; res |= C
  16.817 +	andb	%bl, %al		// current bit
  16.818 +	orb	%al, %bh		// store in bh
  16.819 +	shlb	$1, %bl			// update max
  16.820 +	pop	AX
  16.821 +	loop	RangeDecoder_1
  16.822 +
  16.823 +//   res -= (1 << numLevels); }
  16.824 +
  16.825 +	xchg	AX, BX			// move bh to dh
  16.826 +	xchg	AX, DX			// and dl to al
  16.827 +	sub	%dl, %al		// sub max
  16.828 +	pop	BX
  16.829 +	ret