[alt.sources] Yet another CP/M emulator part 2 of 3

darcy@druid.uucp (D'Arcy J.M. Cain) (11/16/90)

#!/bin/sh
# this is cpm.02 (part 2 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file cpm.c continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 2; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> 'cpm.c' &&
X			return(-1);
X		}
X
X		def_drive = *entry;
X		strcpy(cpm_drive[0],cpm_drive[def_drive]);
X		entry[0] = entry[1] = ' ';
X		tail = chop_cmd(entry);
X	}
X
X	if (*entry == 0)
X		return(0);
X
X	debug(entry);
X
X	if (strcmp(entry, "DIR") == 0)
X		fsystem("ls -C %s", tail);
X	else if (strcmp(entry, "DUMP") == 0)
X		fsystem("hd %s", tail);
X	else if (strcmp(entry, "ED") == 0)
X		fsystem("$EDITOR %s", tail);
X	else if (strcmp(entry, "ERA") == 0)
X		fsystem("rm %s", tail);
#ifdef	CPM_DEBUG
X	else if (strcmp(entry, "DASM") == 0)
X	{
X		if(++dasm_flag > 2)
X			dasm_flag = 0;
X
X		fprintf(stderr, "DASM is %d\r\n", dasm_flag);
X	}
#endif
X	else if (strcmp(entry, "SAVE") == 0)
X	{
X		char	*fname = chop_cmd(tail);
X		int		p = atoi(tail);
X
X		if ((p == 0) || (*fname == 0))
X			fprintf(stderr, "Usage: SAVE #pages filename\r\n");
X		else
X		{
X			if ((fp = fopen(real_name(fname), "wb")) == NULL)
X				perror("\aCan't open save file");
X			else
X			{
X				if (fwrite(ram + 256, 256, p, fp) != p)
X					perror("\aCan't write to file");
X
X				fclose(fp);
X			}
X		}
X	}
X	else if (strcmp(entry, "TYPE") == 0)
X	{
X		char	*ptr;
X
X		while (*tail)
X		{
X			ptr = tail;
X			tail = chop_cmd(ptr);
X			fsystem("cat %s", ptr);
X		}
X	}
X	else if (strcmp(entry, "EXIT") == 0)
X		cleanup(0);
X	else
#ifdef	CPM_DEBUG
X	{
X		time_t	start = time(NULL);
X		int		r = run(real_name(entry));
X
X		fprintf(stderr, "Run took %ld seconds\n\r", time(NULL) - start);
X		return(r);
X	}
#else
X		return(run(real_name(entry)));
#endif
X
X	return(0);
}
#endif
X
void	main(int argc, char **argv)
{
#ifdef	COMPILE_TEST
X	/* test code useful for testing different architectures */
X	int		test;
X
X	test = (int)(&acc);
X	printf("Position of A = %d\n", (int)(&A) - test);
X	printf("Position of FLAGS = %d\n", (int)(&FLAGS) - test);
X
X	test = (int)(&gr);
X	printf("Position of B = %d\n", (int)(&B) - test);
X	printf("Position of C = %d\n", (int)(&C) - test);
X	printf("Position of BC = %d\n", (int)(&BC) - test);
X	printf("Position of D = %d\n", (int)(&D) - test);
X	printf("Position of E = %d\n", (int)(&E) - test);
X	printf("Position of DE = %d\n", (int)(&DE) - test);
X	printf("Position of H = %d\n", (int)(&H) - test);
X	printf("Position of L = %d\n", (int)(&L) - test);
X	printf("Position of HL = %d\n", (int)(&HL) - test);
X
X	AF = 0x1234;
X	printf("AF = %04.4x, A = %02.2x, FLAGS = %02.2x\n", AF, A, FLAGS);
X	printf("Flags: S=%d Z=%d H=%d P=%d N=%d C=%d\n",
X			SIGN, ZERO, HALF_CARRY, PARITY, BCD, CARRY);
X	acc_bank = 1;
X	AF = 0x4321;
X	printf("AF = %04.4x, A = %02.2x, FLAGS = %02.2x\n", AF, A, FLAGS);
X	printf("Flags: S=%d Z=%d H=%d P=%d N=%d C=%d\n",
X			SIGN, ZERO, HALF_CARRY, PARITY, BCD, CARRY);
X
X	BC = 0x2345;
X	printf("BC = %04.4x, B = %02.2x, C = %02.2x\n", BC, B, C);
X	gr_bank = 1;
X	BC = 0x5432;
X	printf("BC = %04.4x, B = %02.2x, C = %02.2x\n", BC, B, C);
X	gr_bank = 0;
X
X	DE = 0x3456;
X	printf("DE = %04.4x, D = %02.2x, E = %02.2x\n", DE, D, E);
X	gr_bank = 1;
X	DE = 0x6543;
X	printf("DE = %04.4x, D = %02.2x, E = %02.2x\n", DE, D, E);
X	gr_bank = 0;
X
X	HL = 0x4567;
X	printf("HL = %04.4x, H = %02.2x, L = %02.2x\n", HL, H, L);
X	gr_bank = 1;
X	HL = 0x7654;
X	printf("HL = %04.4x, H = %02.2x, L = %02.2x\n", HL, H, L);
X	gr_bank = 0;
X
X	A = BC = DE = HL = SP = PC = 0;
X
X	while (PC < TEST_SIZE)
X	{
X		dump_registers(stdout);
X
X		if (decode())
X		{
X			printf("* * * Processor error * * *\n");
X			exit(1);
X		}
X	}
X
X	dump_registers(stdout);
X
X	for (test = 0; test < 0x10; test++)
X		printf("%02.2x ", ram[test]);
X
X	printf("\n");
X	for (test = 0xfff0; test < 0x10000; test++)
X		printf("%02.2x ", ram[test]);
X
X	printf("\nTest code ended normally\n");
X	exit(0);
#else
X
X	char	entry[256];
X	int		c;
X
X	getcwd(cpm_drive[1], 127);
X	entry[0] = 0;
X	debug("");
X
X	while ((c = getopt(argc, argv, "d:c:r:p:h")) != -1)
X	{
X		char	*ptr;
X		int		k;
X
X		switch (c)
X		{
X			case 'd':
X				ptr = optarg + 2;
X
X				if (optarg[1] == ':')
X					k = toupper(*optarg) - '@';
X				else
X				{
X					k = 1;
X					ptr = optarg;
X
X					while ((k < 17) && (*cpm_drive[k]))
X						k++;
X				}
X
X				if ((k < 1) || (k > 16))
X				{
X					fprintf(stderr, "Can't set up %s\n", optarg);
X					exit(1);
X				}
X
X				strcpy(cpm_drive[k], ptr);
X				break;
X
X			case 'c':
X				strcpy(entry, optarg);
X				break;
X
X			case 'r':
X				reader = open_device(optarg, "r");
X				break;
X
X			case 'p':
X				punch = open_device(optarg, "w");
X				break;
X
X			case 'l':
X				list = open_device(optarg, "w");
X				break;
X
X			default:
X				fprintf(stderr,
"Usage:\n");
X				fprintf(stderr,
"cpm [options]\n");
X				fprintf(stderr,
"  Options:\n");
X				fprintf(stderr,
"    -d [d:]directory    map CP/M drive to Unix directory.  If the\n");
X				fprintf(stderr,
"                        second character is not a colon then the next\n");
X				fprintf(stderr,
"                        available drive letter is used otherwise the\n");
X				fprintf(stderr,
"                        letter preceding the colon is used.\n");
X				fprintf(stderr,
"    -c command          runs the command file then exits.  builtins\n");
X				fprintf(stderr,
"                        not supported.  COM file must exist\n");
X				fprintf(stderr,
"    -[r|p|l] dev        This allows the I/O to be routed through the\n");
X				fprintf(stderr,
"                        Unix file system.  The devices mapped are as\n");
X				fprintf(stderr,
"                        follows: r = RDR input, p = PUN output and l for\n");
X				fprintf(stderr,
"                        LST output.  The dev argument is opened as a Unix\n");
X				fprintf(stderr,
"                        file and I/O for specified device is done through\n");
X				fprintf(stderr,
"                        it.  If the first character is '!' then the rest\n");
X				fprintf(stderr,
"                        of the line is taken as a command and popen() is\n");
X				fprintf(stderr,
"                        called to handle the I/O.\n");
X				fprintf(stderr,
"    -h                  Show this help screen\n");
X
X				exit(1);
X		}
X	}
X 
X	strcpy(cpm_drive[0], cpm_drive[1]);
X	def_drive = 1;
X
X	if ((console = open("/dev/tty", O_RDWR)) == -1)
X	{
X		perror("Can't open terminal");
X		exit(1);
X	}
X
X	if (ioctl(console, TCGETA, &old_term) == -1)
X	{
X		perror("Can't get terminal parameters");
X		exit(-1);
X	}
X
X	termp = old_term;
X	termp.c_oflag =  0;
X	termp.c_lflag =  ISIG;
X	termp.c_cc[VEOF] = 1;
X	termp.c_cc[VSWTCH] = 0xff;
X	
X	if (ioctl(console, TCSETA, &termp) == -1)
X	{
X		perror("Can't set terminal parameters");
X		exit(1);
X	}
X
X	signal(SIGHUP, cleanup);
X	signal(SIGINT, cleanup);
X	signal(SIGQUIT, cleanup);
X	signal(SIGTERM, cleanup);
X	debug("Signals captured");
X
X	setbuf(stdout, NULL);
X
X	fprintf(stderr, "\nCP/U - Control Program for Unix\r\n");
X	fprintf(stderr, "CP/M emulator Version 0.900\r\n");
X	fprintf(stderr, "Written by D'Arcy J.M. Cain\r\n");
X	fprintf(stderr, "darcy@druid.UUCP\r\n");
X
X	if (*entry)
X	{
X		do_command(entry);
X		ioctl(console, TCSETA, &old_term);
X		exit(0);
X	}
X
X	debug("Start main loop");
X
X	for (;;)
X	{
X		fprintf(stderr, "%c> ", def_drive + '@');
X		entry[get_str(entry, 128)] = 0;
X
X		if (*entry)
X		{
X			if (do_command(entry) == -1)
X			{
X				debug("chop_cmd(entry)");
X				chop_cmd(entry);
X				debug("strtoup(entry)");
X				strtoup(entry);
X				debug("fprintf(stderr, \"%s?\r\n\", entry)");
X				fprintf(stderr, "%s?\r\n", entry);
X			}
X		}
X	}
#endif
}
SHAR_EOF
chmod 0640 cpm.c ||
echo 'restore of cpm.c failed'
Wc_c="`wc -c < 'cpm.c'`"
test 26758 -eq "$Wc_c" ||
	echo 'cpm.c: original size 26758, current size' "$Wc_c"
# ============= dasm.c ==============
sed 's/^X//' << 'SHAR_EOF' > 'dasm.c' &&
/*
dasm
X
CP/M emulator - instruction disassembler
Written by D'Arcy J.M. Cain
darcy@druid
X
*/
X
#include	<stdio.h>
#include	<string.h>
#include	"cpm.h"
X
#define		get_prog_word(buf)	(buf[1] + (buf[2] << 8))
#define		get_prog_byte(buf)	(*buf)
X
static char		*get_b_reg(int reg)
{
X	switch(reg & 0x07)
X	{
X		case 7:		return("A");
X		case 6:		return("(HL)");
X		case 0:		return("B");
X		case 1:		return("C");
X		case 2:		return("D");
X		case 3:		return("E");
X		case 4:		return("H");
X		case 5:		return("L");
X	}
X
X	return(NULL);
}
X
static char		*get_w_reg(int reg)
{
X	switch (reg & 0x03)
X	{
X		case 2:		return("HL");
X		case 1:		return("DE");
X		case 0:		return("BC");
X		case 3:		return("SP");
X	}
X
X	return(NULL);
}
X
static char		*get_s_reg(int reg)
{
X	switch (reg & 0x03)
X	{
X		case 2:		return("HL");
X		case 1:		return("DE");
X		case 0:		return("BC");
X		case 3:		return("AF");
X	}
X
X	return(NULL);
}
X
static int		relative(int r)
{
X	if (r & 0x80)
X		r |= -256;
X
X	return(PC + r + 2);
}
X
static char		*condition(int word)
{
X	switch (word & 0x07)
X	{
X		case 0:		return("NZ");
X		case 1:		return("Z");
X		case 2:		return("NC");
X		case 3:		return("C");
X		case 4:		return("PO");
X		case 5:		return("PE");
X		case 6:		return("P");
X		case 7:		return("M");
X	}
X
X	return("\a* * * Internal error (condition()) * * *");
}
X
const char 	*dasm(const byte *buf)
{
X	static char	str[32];
X	char		s[32];
X
X	switch (*buf & 0xc0)				/* get class of opcode */
X	{
X		case 0x40:						/* data transfer */
X			if (*buf == 0x76)			/* HALT - special case */
X				return("HALT");
X
X			sprintf(str, "LD\t%s, %s", get_b_reg(*buf >> 3), get_b_reg(*buf));
X			return(str);
X
X		case 0x80:						/* 8 bit math & logic */
X			strcpy(s, get_b_reg(*buf));
X			strcpy(str, "* * * Internal error * * *");
X
math_immediate:							/* comes from misc instructions */
X			switch ((*buf >> 3) & 7)		/* logic op */
X			{
X				case 1:					/* ADC */
X					sprintf(str, "ADC\tA, %s", s);
X					break;
X
X				case 0:					/* ADD */
X					sprintf(str, "ADD\tA, %s", s);
X					break;
X	
X				case 3:					/* SBC */
X					sprintf(str, "SBC\tA, %s", s);
X					break;
X
X				case 2:					/* SUB */
X					sprintf(str, "SUB\tA, %s", s);
X					break;
X
X				case 4:					/* AND */
X					sprintf(str, "AND\tA, %s", s);
X					break;
X
X				case 5:					/* XOR */
X					sprintf(str, "XOR\tA, %s", s);
X					break;
X
X				case 6:					/* OR */
X					sprintf(str, "OR\tA, %s", s);
X					break;
X
X				case 7:					/* CP */
X					sprintf(str, "CP\tA, %s", s);
X					break;
X			}							/* end - logic op */
X
X			return(str);
X
X		case 0xc0:						/* Misc */
X			if ((*buf & 0x07) == 0x06)
X			{
X				sprintf(s, "0%02.2xH", buf[1]);
X				goto math_immediate;	/* sometimes they're necessary */
X			}
X
X			if ((*buf & 0x0f) == 1)		/* POP */
X			{
X				sprintf(str, "POP\t%s", get_s_reg(*buf >> 4));
X				return(str);
X			}
X
X			if ((*buf & 0x0f) == 5)		/* PUSH */
X			{
X				sprintf(str, "PUSH\t%s", get_s_reg(*buf >> 4));
X				return(str);
X			}
X
X
X			switch (*buf & 0x07)		/* BRANCH */
X			{
X				case 0:					/* RET cc */
X					sprintf(str, "RET\t%s", condition(*buf >> 3));
X					return(str);
X
X				case 2:					/* JP cc */
X					sprintf(str, "JP\t%s, 0%02.2x%02.2xH",
X								condition(*buf >> 3), buf[2], buf[1]);
X					return(str);
X
X				case 4:					/* CALL cc */
X					sprintf(str, "CALL\t%s, 0%02.2x%02.2xH",
X								condition(*buf >> 3), buf[2], buf[1]);
X					return(str);
X
X				case 7:					/* RST n */
X					sprintf(str, "RST\t%d", (*buf >> 3) & 0x07);
X					return(str);
X			}							/* end - BRANCH */
X
X			switch (*buf)				/* misc */
X			{
X				case 0xcd:				/* CALL */
X					sprintf(str, "CALL\t0%02.2x%02.2xH", buf[2], buf[1]);
X					return(str);
X
X				case 0xc3:				/* JP */
X					sprintf(str, "JP\t0%02.2x%02.2xH", buf[2], buf[1]);
X					return(str);
X
X				case 0xc9:				/* RET */
X					sprintf(str, "RET");
X					return(str);
X
X				case 0xeb:				/* EX DE, HL */
X					return("EX\tDE, HL");
X
X				case 0xe9:				/* JP (HL) */
X					return("JP\t(HL)");
X
X				case 0xe3:				/* EX (SP), HL */
X					return("EX\t(SP), HL");
X
X				case 0xf9:				/* LD SP, HL */
X					return("LD\tSP, HL");
X
X				case 0xf3:				/* DI */
X					return("DI");
X
X				case 0xfb:				/* EI */
X					return("EI");
X			}								/* misc */
X
X			sprintf(str, "Unrecognized command (0x%02.2x)", *buf);
X			return(str);
X
X		case 0:
X			switch (*buf & 0x07)			/* misc data (3) */
X			{
X				case 4:						/* INC byte */
X					sprintf(str, "INC\t%s", get_b_reg(*buf >> 3));
X					return(str);
X
X				case 5:						/* DEC byte */
X					sprintf(str, "DEC\t%s", get_b_reg(*buf >> 3));
X					return(str);
X
X				case 6:						/* LD byte immediate */
X					sprintf(str, "LD\t%s, 0%02.2xH",
X								get_b_reg(*buf >> 3), buf[1]);
X					return(str);
X			}								/* end - misc data (3) */
X
X			switch (*buf & 0x0f)			/* misc data (4) */
X			{
X				case 1:						/* LD word immediate */
X					sprintf(str, "LD\t%s, 0%02.2x%02.2xH",
X								get_w_reg(*buf >> 4), buf[2], buf[1]);
X					return(str);
X
X				case 0x03:					/* INC word */
X					sprintf(str, "INC\t%s", get_w_reg(*buf >> 4));
X					return(str);
X
X				case 0x0b:					/* DEC word */
X					sprintf(str, "DEC\t%s", get_w_reg(*buf >> 4));
X					return(str);
X
X				case 0x09:					/* ADD HL, ss */
X					sprintf(str, "ADD\tHL, %s", get_w_reg(*buf >> 4));
X					return(str);
X			}								/* end - misc date (4) */
X
X			switch (*buf)					/* misc data */
X			{
X				case 0:						/* NOP */
X					return("NOP");
X
X				case 0x02:					/* LD (BC), A */
X					return("LD\t(BC), A");
X
X				case 0x10:
X					sprintf(str, "DJNZ\t0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x20:
X					sprintf(str, "JR\tNZ, 0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x30:
X					sprintf(str, "JR\tNC, 0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x18:
X					sprintf(str, "JR\t, 0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x28:
X					sprintf(str, "JR\tZ, 0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x38:
X					sprintf(str, "JR\tC, 0%04.4xH", relative(buf[1]));
X					return(str);
X
X				case 0x12:					/* LD (DE), A */
X					return("LD\t(DE), A");
X
X				case 0x22:					/* LD (nn), HL */
X					sprintf(str, "LD\t(0%02.2x%02.2xH), HL", buf[2], buf[1]);
X					return(str);
X
X				case 0x32:					/* LD (nn), A */
X					sprintf(str, "LD\t(0%02.2x%02.2xH), A", buf[2], buf[1]);
X					return(str);
X
X				case 0x0a:					/* LD A, (BC) */
X					return("LD\tA, (BC)");
X
X				case 0x1a:					/* LD A, (DE) */
X					return("LD\tA, (DE)");
X
X				case 0x2a:					/* LD HL, (nn) */
X					sprintf(str, "LD\tHL, (0%02.2x%02.2xH)", buf[2], buf[1]);
X					return(str);
X
X				case 0x3a:					/* LD A, (nn) */
X					sprintf(str, "LD\tA, (0%02.2x%02.2xH)", buf[2], buf[1]);
X					return(str);
X
X				case 7:						/* RLCA */
X					return("RLCA");
X
X				case 0x0f:					/* RRCA */
X					return("RRCA");
X
X				case 0x17:					/* RLA */
X					return("RLA");
X
X				case 0x1f:					/* RRA */
X					return("RRA");
X
X				case 0x27:					/* DAA */
X					return("DAA");
X
X				case 0x2f:					/* CPL */
X					return("CPL");
X
X				case 0x37:					/* SCF */
X					return("SCF");
X
X				case 0x3f:					/* CCF */
X					return("CCF");
X			}								/* end - misc date */
X
X			return("* * * Internal error * * *");
X	}										/* end class */
X
X	return("* * * Internal error * * *");
}
SHAR_EOF
chmod 0640 dasm.c ||
echo 'restore of dasm.c failed'
Wc_c="`wc -c < 'dasm.c'`"
test 7099 -eq "$Wc_c" ||
	echo 'dasm.c: original size 7099, current size' "$Wc_c"
# ============= decode.c ==============
sed 's/^X//' << 'SHAR_EOF' > 'decode.c' &&
/*
X * execute()
X *
X * There are 256 possible opcodes.  The switch statement selects one.
X * $Header: /g/zmob/zrun/RCS/execute.c,v 1.1.1.5 84/04/19 17:51:14 bennet Exp $
X */
X
#include	"cpm.h"
X
static byte	partab[256]=		/* Parity table, 1=even */
{
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
X	1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
};
X
static byte	setmask[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
static byte	resmask[] = { ~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128 };
X
int		pop(void)
{
X	long	r = ram[SP++];
X	return(r + (ram[SP++] << 8));
}
X
void	push(int v)
{
X	ram[--SP] = v >> 8;
X	ram[--SP] = v & 0xff;
}
X
int		decode(void)
{
X	byte	*ptr;
X	long	a, s, s1;
X	byte	opcode = ram[PC++];
X
X	if (PC >= BDOS)
X	{
X		PC = pop();
X		return(0);
X	}
X
X	switch(opcode)
X	{
X	case 0:			/* 00 NOP */
X	when 1:			/* 01 LD BC,nn */
X		C = ram[PC++];
X		B = ram[PC++];
X	when 2:			/* 02 LD (BC),A */
X		ram[BC] = A;
X	when 3:			/* 03 INC BC */
X		++BC;
X	when 4:			/* 04 INC B */
X		HALF_CARRY = (lonyb(B) == 0xf);
X		++B;
X		SIGN = B >> 7;
X		ZERO = B == 0;
X		PARITY = B == 0x80;
X		BCD = 0;
X	when 5:			/* 05 DEC B */
X		HALF_CARRY = lonyb(B) != 0;
X		--B;
X		SIGN = B >> 7;
X		ZERO = B == 0;
X		PARITY = B == 0x7f;
X		BCD = 1;
X	when 6:			/* 06 LD B,n */
X		B = ram[PC++];
X	when 7:			/* 07 RLCA */
X		HALF_CARRY = BCD = 0;
X		CARRY = A >> 7;
X		A = (A << 1);
X		if (CARRY) ++A;
X	when 8:			/* 08 EX AF,AF' */
X		acc_bank = acc_bank ? 0 : 1;
X	when 9:			/* 09 ADD HL,BC */
X		s = BC;
X		a = (HL & 0xfff) + (s & 0xfff);
X		s += HL;
X		HL = s;
X		BCD = 0;
X		CARRY = s >> 16;
X		HALF_CARRY = a >> 12;
X	when 10:		/* 0a LD A,(BC) */
X		A = ram[BC];
X	when 11:		/* 0b DEC BC */
X		--BC;
X	when 12:		/* 0c INC C */
X		HALF_CARRY = lonyb(C) == 0xf;
X		++C;
X		SIGN = C >> 7;
X		ZERO = C == 0;
X		PARITY = C == 0x80;
X		BCD = 0;
X	when 13:		/* 0d DEC C */
X		HALF_CARRY = lonyb(C) != 0;
X		--C;
X		SIGN = C >> 7;
X		ZERO = C == 0;
X		PARITY = C == 0x7f;
X		BCD = 1;
X	when 14:		/* 0e LD C,n */
X		C = ram[PC++];
X	when 15:		/* 0f RRCA */
X		BCD = HALF_CARRY = 0;
X		CARRY = A;
X		A = (A >> 1) | (CARRY ? 128 : 0);
X	when 16:		/* 10 DJNZ e */
X		s = (int)(ram[PC++]);
X		if (--B) PC += s;
X	when 17:		/* 11 LD DE,nn */
X		E = ram[PC++];
X		D = ram[PC++];
X	when 18:		/* 12 LD (DE),A */
X		ram[DE] = A;
X	when 19:		/* 13 INC DE */
X		++DE;
X	when 20:		/* 14 INC D */
X		HALF_CARRY = lonyb(D) == 0xf;
X		++D;
X		SIGN = D >> 7;
X		ZERO = D == 0;
X		PARITY = D == 0x80;
X		BCD = 0;
X	when 21:		/* 15 DEC D */
X		HALF_CARRY = lonyb(D) != 0;
X		--D;
X		SIGN = D >> 7;
X		ZERO = D == 0;
X		PARITY = D == 0x7f;
X		BCD = 1;
X	when 22:		/* 16 LD D,n */
X		D = ram[PC++];
X	when 23:		/* 17 RLA */
X		s = A << 1;
X		A = s | CARRY;
X		CARRY = s >> 8;
X		BCD = HALF_CARRY = 0;
X	when 24:		/* 18 JR e */
X		PC += (int)(ram[PC]);
X	when 25:		/* 19 ADD HL,DE */
X		s = DE;
X		a = (HL & 0xfff) + (s & 0xfff);
X		s += HL;
X		HL = s;
X		BCD = 0;
X		CARRY = s >> 16;
X		HALF_CARRY = a >> 12;
X	when 26:		/* 1a LD A,(DE) */
X		A = ram[DE];
X	when 27:		/* 1b DEC DE */
X		--DE;
X	when 28:		/* 1c INC E */
X		HALF_CARRY = lonyb(E) == 0xf;
X		++E;
X		SIGN = E >> 7;
X		ZERO = E == 0;
X		PARITY = E == 0x80;
X		BCD = 0;
X	when 29:		/* 1d DEC E */
X		HALF_CARRY = lonyb(E) != 0;
X		--E;
X		SIGN = E >> 7;
X		ZERO = E == 0;
X		PARITY = E == 0x7f;
X		BCD = 1;
X	when 30:		/* 1e LD E,n */
X		E = ram[PC++];
X	when 31:		/* 1f RRA */
X		CARRY = (s = A | (CARRY << 8));
X		A = s >> 1;
X		BCD = HALF_CARRY = 0;
X	when 32:		/* 20 JR NZ,e */
X		if (ZERO) ++PC;
X		else PC += (int)(ram[PC]);
X	when 33:		/* 21 LD HL,nn */
X		L = ram[PC++];
X		H = ram[PC++];
X	when 34:		/* 22 LD (nn),HL */
X		TEMPL = ram[PC++];
X		TEMPH = ram[PC++];
X		ram[TEMP] = L;
X		ram[TEMP + 1] = H;
X	when 35:		/* 23 INC HL */
X		++HL;
X	when 36:		/* 24 INC H */
X		HALF_CARRY = lonyb(H) == 0xf;
X		++H;
X		SIGN = H >> 7;
X		ZERO = H == 0;
X		PARITY = H == 0x80;
X		BCD = 0;
X	when 37:		/* 25 DEC H */
X		HALF_CARRY = lonyb(H) != 0;
X		--H;
X		SIGN = H >> 7;
X		ZERO = H == 0;
X		PARITY = H == 0x7f;
X		BCD = 1;
X	when 38:		/* 26 LD H,n */
X		H = ram[PC++];
X	when 39:		/* 27 DAA */
X		s = A & 0x0f;
X		a = (A >> 4) & 0x0f;
X		s1 = 0;
X
X		if (BCD)
X		{
X			if (CARRY)
X			{
X				if (HALF_CARRY)
X					s1 = ((a > 5) && (s > 5)) ? 0x9a : 0;
X				else
X					s1 = ((a > 6) && (s < 10)) ? 0xa0 : 0;
X			}
X			else
X				if(HALF_CARRY)
X					s1 = ((a < 9) && (s > 5)) ? 0xfa : 0;
X		}
X		else
X		{
X			if (CARRY)
X			{
X				if(HALF_CARRY)
X					s1 = ((a < 4) && (s < 4)) ? 0x66 : 0;
X				else if (a < 3)
X					s1 = (s < 10) ? 0x60 : 0x66;
X			}
X			else
X			{
X				if(HALF_CARRY)
X				{
X					if (s < 4)
X						if (a > 9)
X						{
X							s1 = 0x66;
X							CARRY = 1;
X						}
X						else s1 = 0x06;
X				}
X				else
X				{
X					if ((a > 8) && (s > 9))
X					{
X						s1 = 0x66;
X						CARRY = 1;
X					}
X					else if ((a > 9) && (s < 10))
X					{
X						s1 = 0x60;
X						CARRY = 1;
X					}
X					else if ((a < 10) && (s < 10))
X							;
X					else if ((a < 9) && (s > 9))
X						s1 = 6;
X				}
X			}
X		}
X
X		HALF_CARRY = ((int)(A) + (int)(s1)) > 0xf;
X		A += s1;
X		SIGN = A >> 7;
X		ZERO = (A == 0);
X		PARITY = partab[A];
X	when 40:		/* 28 JR Z,e */
X		if (ZERO) PC += (int)(ram[PC]);
X		else ++PC;
X	when 41:		/* 29 ADD HL,HL */
X		s = HL;
X		a = (HL & 0xfff) + (s & 0xfff);
X		s += HL;
X		HL = s;
X		BCD = 0;
X		CARRY = s >> 16;
X		HALF_CARRY = a >> 12;
X	when 42:		/* 2a LD HL,(nn) */
X		TEMPL = ram[PC++];
X		TEMPH = ram[PC++];
X		L = ram[TEMP];
X		H = ram[TEMP + 1];
X	when 43:		/* 2b DEC HL */
X		--HL;
X	when 44:		/* 2c INC L */
X		HALF_CARRY = lonyb(L) == 0xf;
X		++L;
X		SIGN = L >> 7;
X		ZERO = L == 0;
X		PARITY = L == 0x80;
X		BCD = 0;
X	when 45:		/* 2d DEC L */
X		HALF_CARRY = lonyb(L) != 0;
X		--L;
X		SIGN = L >> 7;
X		ZERO = L == 0;
X		PARITY = L == 0x7f;
X		BCD = 1;
X	when 46:		/* 2e LD L,n */
X		L = ram[PC++];
X	when 47:		/* 2f CPL */
X		A = ~A;
X		HALF_CARRY = BCD = 1;
X	when 48:		/* 30 JR NC,e */
X		if(CARRY) ++PC;
X		else PC += (int)(ram[PC]);
X	when 49:		/* 31 LD SP,nn */
X		SPL = ram[PC++];
X		SPH = ram[PC++];
X	when 50:		/* 32 LD (nn),A */
X		TEMPL = ram[PC++];
X		TEMPH = ram[PC++];
X		ram[TEMP] = A;
X	when 51:		/* 33 INC SP */
X		++SP;
X	when 52:		/* 34 INC (HL) */
X		HALF_CARRY = lonyb(ram[HL]) == 0xf;
X		++ram[HL];
X		SIGN = ram[HL] >> 7;
X		ZERO = ram[HL] == 0;
X		PARITY = ram[HL] == 0x80;
X		BCD = 0;
X	when 53:		/* 35 DEC (HL) */
X		HALF_CARRY = lonyb(ram[HL]) != 0;
X		--ram[HL];
X		SIGN = ram[HL] >> 7;
X		ZERO = ram[HL] == 0;
X		PARITY = ram[HL] == 0x7f;
X		BCD = 1;
X	when 54:		/* 36 LD (HL),n */
X		ram[HL] = ram[PC++];
X	when 55:		/* 37 SCF */
X		HALF_CARRY = BCD = 0;
X		CARRY = 1;
X	when 56:		/* 38 JR C,e */
X		if (CARRY) PC += (int)(ram[PC]);
X		else ++PC;
X	when 57:		/* 39 ADD HL,SP */
X		s = SP;
X		a = (HL & 0xfff) + (s & 0xfff);
X		s += HL;
X		HL = s;
X		BCD = 0;
X		CARRY = s >> 16;
X		HALF_CARRY = a >> 12;
X	when 58:		/* 3a LD A,(nn) */
X		TEMPL = ram[PC++];
X		TEMPH = ram[PC++];
X		A = ram[TEMP];
X	when 59:		/* 3b DEC SP */
X		--SP;
X	when 60:		/* 3c INC A */
X		HALF_CARRY = lonyb(A) == 0xf;
X		++A;
X		SIGN = A >> 7;
X		ZERO = A == 0;
X		PARITY = A == 0x80;
X		BCD = 0;
X	when 61:		/* 3d DEC A */
X		HALF_CARRY = lonyb(A) != 0;
X		--A;
X		SIGN = A >> 7;
X		ZERO = A == 0;
X		PARITY = A == 0x7f;
X		BCD = 1;
X	when 62:		/* 3e LD A,n */
X		A = ram[PC++];
X	when 63:		/* 3f CCF */
X		HALF_CARRY = CARRY;
X		CARRY = ~CARRY;
X		BCD = 0;
X	when 64:		/* 40 LD B,B */
X	when 65:		/* 41 LD B,C */
X		B = C;
X	when 66:		/* 42 LD B,D */
X		B = D;
X	when 67:		/* 43 LD B,E */
X		B = E;
X	when 68:		/* 44 LD B,H */
X		B = H;
X	when 69:		/* 45 LD B,L */
X		B = L;
X	when 70:		/* 46 LD B, (HL) */
X		B = ram[HL];
X	when 71:		/* 47 LD B,A */
X		B = A;
X	when 72:		/* 48 LD C,B */
X		C = B;
X	when 73:		/* 49 LD C,C */
X	when 74:		/* 4a LD C,D */
X		C = D;
X	when 75:		/* 4b LD C,E */
X		C = E;
X	when 76:		/* 4c LD C,H */
X		C = H;
X	when 77:		/* 4d LD C,L */
X		C = L;
X	when 78:		/* 4e LD C, (HL) */
X		C = ram[HL];
X	when 79:		/* 4f LD C,A */
X		C = A;
X	when 80:		/* 50 LD D,B */
X		D = B;
X	when 81:		/* 51 LD D,C */
X		D = C;
X	when 82:		/* 52 LD D,D */
X	when 83:		/* 53 LD D,E */
X		D = E;
X	when 84:		/* 54 LD D,H */
X		D = H;
X	when 85:		/* 55 LD D,L */
X		D = L;
X	when 86:		/* 56 LD D, (HL) */
X		D = ram[HL];
X	when 87:		/* 57 LD D,A */
X		D = A;
X	when 88:		/* 58 LD E,B */
X		E = B;
X	when 89:		/* 59 LD E,C */
X		E = C;
X	when 90:		/* 5a LD E,D */
X		E = D;
X	when 91:		/* 5b LD E,E */
X	when 92:		/* 5c LD E,H */
X		E = H;
X	when 93:		/* 5d LD E,L */
X		E = L;
X	when 94:		/* 5e LD E, (HL) */
X		E = ram[HL];
X	when 95:		/* 5f LD E,A */
X		E = A;
X	when 96:		/* 60 LD H,B */
X		H = B;
X	when 97:		/* 61 LD H,C */
X		H = C;
X	when 98:		/* 62 LD H,D */
X		H = D;
X	when 99:		/* 63 LD H,E */
X		H = E;
X	when 100:		/* 64 LD H,H */
X	when 101:		/* 65 LD H,L */
X		H = L;
X	when 102:		/* 66 LD H, (HL) */
X		H = ram[HL];
X	when 103:		/* 67 LD H,A */
X		H = A;
X	when 104:		/* 68 LD L,B */
X		L = B;
X	when 105:		/* 69 LD L,C */
X		L = C;
X	when 106:		/* 6a LD L,D */
X		L = D;
X	when 107:		/* 6b LD L,E */
X		L = E;
X	when 108:		/* 6c LD L,H */
X		L = H;
X	when 109:		/* 6d LD L,L */
X	when 110:		/* 6e LD L,(HL) */
X		L = ram[HL];
X	when 111:		/* 6f LD L,A */
X		L = A;
X	when 112:		/* 70 LD (HL),B */
X		ram[HL] = B;
X	when 113:		/* 71 LD (HL),C */
X		ram[HL] = C;
X	when 114:		/* 72 LD (HL),D */
X		ram[HL] = D;
X	when 115:		/* 73 LD (HL),E */
X		ram[HL] = E;
X	when 116:		/* 74 LD (HL),H */
X		ram[HL] = H;
X	when 117:		/* 75 LD (HL),L */
X		ram[HL] = L;
X	when 118:		/* 76 HALT */
X		return(0x76);
X	when 119:		/* 77 LD (HL),A */
X		ram[HL] = A;
X	when 120:		/* 78 LD A,B */
X		A = B;
X	when 121:		/* 79 LD A,C */
X		A = C;
X	when 122:		/* 7a LD A,D */
X		A = D;
X	when 123:		/* 7b LD A,E */
X		A = E;
X	when 124:		/* 7c LD A,H */
X		A = H;
X	when 125:		/* 7d LD A,L */
X		A = L;
X	when 126:		/* 7e LD A,(HL) */
X		A = ram[HL];
X	when 127:		/* 7f LD A,A */
X	when 128:		/* 80 ADD A,B */
X		s = B;
X		goto add;
X	case 129:		/* 81 ADD A,C */
X		s = C;
X		goto add;
X	case 130:		/* 82 ADD A,D */
X		s = D;
X		goto add;
X	case 131:		/* 83 ADD A,E */
X		s = E;
X		goto add;
X	case 132:		/* 84 ADD A,H */
X		s = H;
X		goto add;
X	case 133:		/* 85 ADD A,L */
X		s = L;
X		goto add;
X	case 134:		/* 86 ADD A,(HL) */
X		s = ram[HL];
X		goto add;
X	case 135:		/* 87 ADD A,A */
X		s = A;
X		goto add;
X	case 136:		/* 88 ADC A,B */
X		s = B;
X		goto adc;
X	case 137:		/* 89 ADC A,C */
X		s = C;
X		goto adc;
X	case 138:		/* 8a ADC A,D */
X		s = D;
X		goto adc;
X	case 139:		/* 8b ADC A,E */
X		s = E;
X		goto adc;
X	case 140:		/* 8c ADC A,H */
X		s = H;
X		goto adc;
X	case 141:		/* 8d ADC A,L */
X		s = L;
X		goto adc;
X	case 142:		/* 8e ADC A,(HL) */
X		s = ram[HL];
X		goto adc;
X	case 143:		/* 8f ADC A,A */
X		s = A;
X
adc:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X		if (CARRY) { s++; a++; }
X		goto add1;
X
add:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X
add1:
X		BCD = 0;
X		s += A;
X		A = s;
X		a += s1;
X
set_flags:
X		CARRY = s >> 8;
X		HALF_CARRY = a >> 4;
X		SIGN = s >> 7;
X		ZERO = s ? 0 : 1;
X		PARITY = partab[A];
X
X	when 144:		/* 90 SUB A,B */
X		s = B;
X		goto sub;
X	case 145:		/* 91 SUB A,C */
X		s = C;
X		goto sub;
X	case 146:		/* 92 SUB A,D */
X		s = D;
X		goto sub;
X	case 147:		/* 93 SUB A,E */
X		s = E;
X		goto sub;
X	case 148:		/* 94 SUB A,H */
X		s = H;
X		goto sub;
X	case 149:		/* 95 SUB A,L */
X		s = L;
X		goto sub;
X	case 150:		/* 96 SUB A,(HL) */
X		s = ram[HL];
X		goto sub;
X	case 151:		/* 97 SUB A,A */
X		s = A;
X		goto sub;
X	case 152:		/* 98 SBC A,B */
X		s = B;
X		goto sbc;
X	case 153:		/* 99 SBC A,C */
X		s = C;
X		goto sbc;
X	case 154:		/* 9a SBC A,D */
X		s = D;
X		goto sbc;
X	case 155:		/* 9b SBC A,E */
X		s = E;
X		goto sbc;
X	case 156:		/* 9c SBC A,H */
X		s = H;
X		goto sbc;
X	case 157:		/* 9d SBC A,L */
X		s = L;
X		goto sbc;
X	case 158:		/* 9e SBC A,(HL) */
X		s = ram[HL];
X		goto sbc;
X	when 159:		/* 9f SBC A,A */
X		s = A;
X
sbc:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X		if (CARRY) { s--; a--; }
X		goto sub1;
X
sub:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X
sub1:
X		s = A - s;
X		A = s;
X		a -= s1;
X		BCD = 1;
X		goto set_flags;
X
X	when 160:		/* a0 AND A,B */
X		s = B;
X		goto and;
X	case 161:		/* a1 AND A,C */
X		s = C;
X		goto and;
X	case 162:		/* a2 AND A,D */
X		s = D;
X		goto and;
X	case 163:		/* a3 AND A,E */
X		s = E;
X		goto and;
X	case 164:		/* a4 AND A,H */
X		s = H;
X		goto and;
X	case 165:		/* a5 AND A,L */
X		s = L;
X		goto and;
X	case 166:		/* a6 AND A,(HL) */
X		s = ram[HL];
X		goto and;
X	case 167:		/* a7 AND A,A */
X		s = A;
X
and:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X
X		s &= A;
X		A = s;
X		a &= s;
X		goto set_flags;
X		
X	when 168:		/* a8 XOR A,B */
X		s = B;
X		goto xor;
X	case 169:		/* a9 XOR A,C */
X		s = C;
X		goto xor;
X	case 170:		/* aa XOR A,D */
X		s = D;
X		goto xor;
X	case 171:		/* ab XOR A,E */
X		s = E;
X		goto xor;
X	case 172:		/* ac XOR A,H */
X		s = H;
X		goto xor;
X	case 173:		/* ad XOR A,L */
X		s = L;
X		goto xor;
X	case 174:		/* ae XOR A,(HL) */
X		s = ram[HL];
X		goto xor;
X	case 175:		/* af XOR A,A */
X		s = A;
X
xor:
X		a = A & 0x0f;
X		s1 = s & 0x0f;
X
X		s ^= A;
X		A = s;
X		a ^= s;
X		goto set_flags;
X
X	when 176:		/* b1 OR B */
X		s = B;
X		goto or;
X	case 177:		/* b1 OR C */
X		s = C;
X		goto or;
X	case 178:		/* b2 OR D */
X		s = D;
X		goto or;
X	case 179:		/* b3 OR E */
X		s = E;
X		goto or;
X	case 180:		/* b4 OR H */
X		s = H;
X		goto or;
X	case 181:		/* b5 OR L */
X		s = L;
X		goto or;
X	case 182:		/* b6 OR (HL) */
SHAR_EOF
true || echo 'restore of decode.c failed'
echo 'End of part 2, continue with part 3'
echo 3 > _shar_seq_.tmp
exit 0

-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   I support gun control.
West Hill, Ontario, Canada         |   Let's start with the government!
+ 416 281 6094                     |