copy all local files to repo

cp/m files, sprites, circuit design
This commit is contained in:
Amber
2020-05-15 09:07:45 -04:00
parent 8353edd599
commit 783d32a495
461 changed files with 80153 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
# Makefile for Z80-CPU emulator unter UNIX System V
CFLAGS= -O -c -Wall
LFLAGS= -s
#CFLAGS= -g -c -Wall
#LFLAGS=
OBJ = sim0.o \
sim1.o \
sim2.o \
sim3.o \
sim4.o \
sim5.o \
sim6.o \
sim7.o \
simctl.o \
disas.o \
simint.o \
iosim.o \
simfun.o \
simglb.o
z80sim : $(OBJ)
cc $(OBJ) $(LFLAGS) -o z80sim
sim0.o : sim0.c sim.h simglb.h
cc $(CFLAGS) sim0.c
sim1.o : sim1.c sim.h simglb.h
cc $(CFLAGS) sim1.c
sim2.o : sim2.c sim.h simglb.h
cc $(CFLAGS) sim2.c
sim3.o : sim3.c sim.h simglb.h
cc $(CFLAGS) sim3.c
sim4.o : sim4.c sim.h simglb.h
cc $(CFLAGS) sim4.c
sim5.o : sim5.c sim.h simglb.h
cc $(CFLAGS) sim5.c
sim6.o : sim6.c sim.h simglb.h
cc $(CFLAGS) sim6.c
sim7.o : sim7.c sim.h simglb.h
cc $(CFLAGS) sim7.c
simctl.o : simctl.c sim.h simglb.h
cc $(CFLAGS) simctl.c
disas.o : disas.c
cc $(CFLAGS) disas.c
simint.o : simint.c sim.h simglb.h
cc $(CFLAGS) simint.c
iosim.o : iosim.c sim.h simglb.h
cc $(CFLAGS) iosim.c
simfun.o : simfun.c sim.h
cc $(CFLAGS) simfun.c
simglb.o : simglb.c sim.h
cc $(CFLAGS) simglb.c
clean:
rm -f *.o core z80sim

View File

@@ -0,0 +1,883 @@
/*
* Z80 disassembler for Z80-CPU simulator
*
* Copyright (C) 1989-2006 by Udo Munk
*
* History:
* 06-DEC-89 Development on TARGON/35 with AT&T Unix System V.3
* 07-APR-92 forget to implement Op-Codes LD A,R and LD R,A, added
* 25-JUN-92 comments in english
* 03-OCT-06 changed to ANSI C for modern POSIX OS's
*/
#include <stdio.h>
/*
* Forward declarations
*/
static int opout(char *, char **);
static int nout(char *, unsigned char **);
static int iout(char *, unsigned char **);
static int rout(char *, char **);
static int nnout(char *, unsigned char **);
static int inout(char *, unsigned char **);
static int cbop(char *, unsigned char **);
static int edop(char *, unsigned char **);
static int ddfd(char *, unsigned char **);
/*
* Op-code tables
*/
struct opt {
int (*fun) ();
char *text;
};
static struct opt optab[256] = {
{ opout, "NOP" }, /* 0x00 */
{ nnout, "LD\tBC," }, /* 0x01 */
{ opout, "LD\t(BC),A" }, /* 0x02 */
{ opout, "INC\tBC" }, /* 0x03 */
{ opout, "INC\tB" }, /* 0x04 */
{ opout, "DEC\tB" }, /* 0x05 */
{ nout, "LD\tB," }, /* 0x06 */
{ opout, "RLCA" }, /* 0x07 */
{ opout, "EX\tAF,AF'" }, /* 0x08 */
{ opout, "ADD\tHL,BC" }, /* 0x09 */
{ opout, "LD\tA,(BC)" }, /* 0x0a */
{ opout, "DEC\tBC" }, /* 0x0b */
{ opout, "INC\tC" }, /* 0x0c */
{ opout, "DEC\tC" }, /* 0x0d */
{ nout, "LD\tC," }, /* 0x0e */
{ opout, "RRCA" }, /* 0x0f */
{ rout, "DJNZ\t" }, /* 0x10 */
{ nnout, "LD\tDE," }, /* 0x11 */
{ opout, "LD\t(DE),A" }, /* 0x12 */
{ opout, "INC\tDE" }, /* 0x13 */
{ opout, "INC\tD" }, /* 0x14 */
{ opout, "DEC\tD" }, /* 0x15 */
{ nout, "LD\tD," }, /* 0x16 */
{ opout, "RLA" }, /* 0x17 */
{ rout, "JR\t" }, /* 0x18 */
{ opout, "ADD\tHL,DE" }, /* 0x19 */
{ opout, "LD\tA,(DE)" }, /* 0x1a */
{ opout, "DEC\tDE" }, /* 0x1b */
{ opout, "INC\tE" }, /* 0x1c */
{ opout, "DEC\tE" }, /* 0x1d */
{ nout, "LD\tE," }, /* 0x1e */
{ opout, "RRA" }, /* 0x1f */
{ rout, "JR\tNZ," }, /* 0x20 */
{ nnout, "LD\tHL," }, /* 0x21 */
{ inout, "LD\t(%04x),HL" }, /* 0x22 */
{ opout, "INC\tHL" }, /* 0x23 */
{ opout, "INC\tH" }, /* 0x24 */
{ opout, "DEC\tH" }, /* 0x25 */
{ nout, "LD\tH," }, /* 0x26 */
{ opout, "DAA" }, /* 0x27 */
{ rout, "JR\tZ," }, /* 0x28 */
{ opout, "ADD\tHL,HL" }, /* 0x29 */
{ inout, "LD\tHL,(%04x)" }, /* 0x2a */
{ opout, "DEC\tHL" }, /* 0x2b */
{ opout, "INC\tL" }, /* 0x2c */
{ opout, "DEC\tL" }, /* 0x2d */
{ nout, "LD\tL," }, /* 0x2e */
{ opout, "CPL" }, /* 0x2f */
{ rout, "JR\tNC," }, /* 0x30 */
{ nnout, "LD\tSP," }, /* 0x31 */
{ inout, "LD\t(%04x),A" }, /* 0x32 */
{ opout, "INC\tSP" }, /* 0x33 */
{ opout, "INC\t(HL)" }, /* 0x34 */
{ opout, "DEC\t(HL)" }, /* 0x35 */
{ nout, "LD\t(HL)," }, /* 0x36 */
{ opout, "SCF" }, /* 0x37 */
{ rout, "JR\tC," }, /* 0x38 */
{ opout, "ADD\tHL,SP" }, /* 0x39 */
{ inout, "LD\tA,(%04x)" }, /* 0x3a */
{ opout, "DEC\tSP" }, /* 0x3b */
{ opout, "INC\tA" }, /* 0x3c */
{ opout, "DEC\tA" }, /* 0x3d */
{ nout, "LD\tA," }, /* 0x3e */
{ opout, "CCF" }, /* 0x3f */
{ opout, "LD\tB,B" }, /* 0x40 */
{ opout, "LD\tB,C" }, /* 0x41 */
{ opout, "LD\tB,D" }, /* 0x42 */
{ opout, "LD\tB,E" }, /* 0x43 */
{ opout, "LD\tB,H" }, /* 0x44 */
{ opout, "LD\tB,L" }, /* 0x45 */
{ opout, "LD\tB,(HL)" }, /* 0x46 */
{ opout, "LD\tB,A" }, /* 0x47 */
{ opout, "LD\tC,B" }, /* 0x48 */
{ opout, "LD\tC,C" }, /* 0x49 */
{ opout, "LD\tC,D" }, /* 0x4a */
{ opout, "LD\tC,E" }, /* 0x4b */
{ opout, "LD\tC,H" }, /* 0x4c */
{ opout, "LD\tC,L" }, /* 0x4d */
{ opout, "LD\tC,(HL)" }, /* 0x4e */
{ opout, "LD\tC,A" }, /* 0x4f */
{ opout, "LD\tD,B" }, /* 0x50 */
{ opout, "LD\tD,C" }, /* 0x51 */
{ opout, "LD\tD,D" }, /* 0x52 */
{ opout, "LD\tD,E" }, /* 0x53 */
{ opout, "LD\tD,H" }, /* 0x54 */
{ opout, "LD\tD,L" }, /* 0x55 */
{ opout, "LD\tD,(HL)" }, /* 0x56 */
{ opout, "LD\tD,A" }, /* 0x57 */
{ opout, "LD\tE,B" }, /* 0x58 */
{ opout, "LD\tE,C" }, /* 0x59 */
{ opout, "LD\tE,D" }, /* 0x5a */
{ opout, "LD\tE,E" }, /* 0x5b */
{ opout, "LD\tE,H" }, /* 0x5c */
{ opout, "LD\tE,L" }, /* 0x5d */
{ opout, "LD\tE,(HL)" }, /* 0x5e */
{ opout, "LD\tE,A" }, /* 0x5f */
{ opout, "LD\tH,B" }, /* 0x60 */
{ opout, "LD\tH,C" }, /* 0x61 */
{ opout, "LD\tH,D" }, /* 0x62 */
{ opout, "LD\tH,E" }, /* 0x63 */
{ opout, "LD\tH,H" }, /* 0x64 */
{ opout, "LD\tH,L" }, /* 0x65 */
{ opout, "LD\tH,(HL)" }, /* 0x66 */
{ opout, "LD\tH,A" }, /* 0x67 */
{ opout, "LD\tL,B" }, /* 0x68 */
{ opout, "LD\tL,C" }, /* 0x69 */
{ opout, "LD\tL,D" }, /* 0x6a */
{ opout, "LD\tL,E" }, /* 0x6b */
{ opout, "LD\tL,H" }, /* 0x6c */
{ opout, "LD\tL,L" }, /* 0x6d */
{ opout, "LD\tL,(HL)" }, /* 0x6e */
{ opout, "LD\tL,A" }, /* 0x6f */
{ opout, "LD\t(HL),B" }, /* 0x70 */
{ opout, "LD\t(HL),C" }, /* 0x71 */
{ opout, "LD\t(HL),D" }, /* 0x72 */
{ opout, "LD\t(HL),E" }, /* 0x73 */
{ opout, "LD\t(HL),H" }, /* 0x74 */
{ opout, "LD\t(HL),L" }, /* 0x75 */
{ opout, "HALT" }, /* 0x76 */
{ opout, "LD\t(HL),A" }, /* 0x77 */
{ opout, "LD\tA,B" }, /* 0x78 */
{ opout, "LD\tA,C" }, /* 0x79 */
{ opout, "LD\tA,D" }, /* 0x7a */
{ opout, "LD\tA,E" }, /* 0x7b */
{ opout, "LD\tA,H" }, /* 0x7c */
{ opout, "LD\tA,L" }, /* 0x7d */
{ opout, "LD\tA,(HL)" }, /* 0x7e */
{ opout, "LD\tA,A" }, /* 0x7f */
{ opout, "ADD\tA,B" }, /* 0x80 */
{ opout, "ADD\tA,C" }, /* 0x81 */
{ opout, "ADD\tA,D" }, /* 0x82 */
{ opout, "ADD\tA,E" }, /* 0x83 */
{ opout, "ADD\tA,H" }, /* 0x84 */
{ opout, "ADD\tA,L" }, /* 0x85 */
{ opout, "ADD\tA,(HL)" }, /* 0x86 */
{ opout, "ADD\tA,A" }, /* 0x87 */
{ opout, "ADC\tA,B" }, /* 0x88 */
{ opout, "ADC\tA,C" }, /* 0x89 */
{ opout, "ADC\tA,D" }, /* 0x8a */
{ opout, "ADC\tA,E" }, /* 0x8b */
{ opout, "ADC\tA,H" }, /* 0x8c */
{ opout, "ADC\tA,L" }, /* 0x8d */
{ opout, "ADC\tA,(HL)" }, /* 0x8e */
{ opout, "ADC\tA,A" }, /* 0x8f */
{ opout, "SUB\tB" }, /* 0x90 */
{ opout, "SUB\tC" }, /* 0x91 */
{ opout, "SUB\tD" }, /* 0x92 */
{ opout, "SUB\tE" }, /* 0x93 */
{ opout, "SUB\tH" }, /* 0x94 */
{ opout, "SUB\tL" }, /* 0x95 */
{ opout, "SUB\t(HL)" }, /* 0x96 */
{ opout, "SUB\tA" }, /* 0x97 */
{ opout, "SBC\tA,B" }, /* 0x98 */
{ opout, "SBC\tA,C" }, /* 0x99 */
{ opout, "SBC\tA,D" }, /* 0x9a */
{ opout, "SBC\tA,E" }, /* 0x9b */
{ opout, "SBC\tA,H" }, /* 0x9c */
{ opout, "SBC\tA,L" }, /* 0x9d */
{ opout, "SBC\tA,(HL)" }, /* 0x9e */
{ opout, "SBC\tA,A" }, /* 0x9f */
{ opout, "AND\tB" }, /* 0xa0 */
{ opout, "AND\tC" }, /* 0xa1 */
{ opout, "AND\tD" }, /* 0xa2 */
{ opout, "AND\tE" }, /* 0xa3 */
{ opout, "AND\tH" }, /* 0xa4 */
{ opout, "AND\tL" }, /* 0xa5 */
{ opout, "AND\t(HL)" }, /* 0xa6 */
{ opout, "AND\tA" }, /* 0xa7 */
{ opout, "XOR\tB" }, /* 0xa8 */
{ opout, "XOR\tC" }, /* 0xa9 */
{ opout, "XOR\tD" }, /* 0xaa */
{ opout, "XOR\tE" }, /* 0xab */
{ opout, "XOR\tH" }, /* 0xac */
{ opout, "XOR\tL" }, /* 0xad */
{ opout, "XOR\t(HL)" }, /* 0xae */
{ opout, "XOR\tA" }, /* 0xaf */
{ opout, "OR\tB" }, /* 0xb0 */
{ opout, "OR\tC" }, /* 0xb1 */
{ opout, "OR\tD" }, /* 0xb2 */
{ opout, "OR\tE" }, /* 0xb3 */
{ opout, "OR\tH" }, /* 0xb4 */
{ opout, "OR\tL" }, /* 0xb5 */
{ opout, "OR\t(HL)" }, /* 0xb6 */
{ opout, "OR\tA" }, /* 0xb7 */
{ opout, "CP\tB" }, /* 0xb8 */
{ opout, "CP\tC" }, /* 0xb9 */
{ opout, "CP\tD" }, /* 0xba */
{ opout, "CP\tE" }, /* 0xbb */
{ opout, "CP\tH" }, /* 0xbc */
{ opout, "CP\tL" }, /* 0xbd */
{ opout, "CP\t(HL)" }, /* 0xbe */
{ opout, "CP\tA" }, /* 0xbf */
{ opout, "RET\tNZ" }, /* 0xc0 */
{ opout, "POP\tBC" }, /* 0xc1 */
{ nnout, "JP\tNZ," }, /* 0xc2 */
{ nnout, "JP\t" }, /* 0xc3 */
{ nnout, "CALL\tNZ," }, /* 0xc4 */
{ opout, "PUSH\tBC" }, /* 0xc5 */
{ nout, "ADD\tA," }, /* 0xc6 */
{ opout, "RST\t0" }, /* 0xc7 */
{ opout, "RET\tZ" }, /* 0xc8 */
{ opout, "RET" }, /* 0xc9 */
{ nnout, "JP\tZ," }, /* 0xca */
{ cbop, "" }, /* 0xcb */
{ nnout, "CALL\tZ," }, /* 0xcc */
{ nnout, "CALL\t" }, /* 0xcd */
{ nout, "ADC\tA," }, /* 0xce */
{ opout, "RST\t8" }, /* 0xcf */
{ opout, "RET\tNC" }, /* 0xd0 */
{ opout, "POP\tDE" }, /* 0xd1 */
{ nnout, "JP\tNC," }, /* 0xd2 */
{ iout, "OUT\t(%02x),A" }, /* 0xd3 */
{ nnout, "CALL\tNC," }, /* 0xd4 */
{ opout, "PUSH\tDE" }, /* 0xd5 */
{ nout, "SUB\t" }, /* 0xd6 */
{ opout, "RST\t10" }, /* 0xd7 */
{ opout, "RET\tC" }, /* 0xd8 */
{ opout, "EXX" }, /* 0xd9 */
{ nnout, "JP\tC," }, /* 0xda */
{ iout, "IN\tA,(%02x)" }, /* 0xdb */
{ nnout, "CALL\tC," }, /* 0xdc */
{ ddfd, "" }, /* 0xdd */
{ nout, "SBC\tA," }, /* 0xde */
{ opout, "RST\t18" }, /* 0xdf */
{ opout, "RET\tPO" }, /* 0xe0 */
{ opout, "POP\tHL" }, /* 0xe1 */
{ nnout, "JP\tPO," }, /* 0xe2 */
{ opout, "EX\t(SP),HL" }, /* 0xe3 */
{ nnout, "CALL\tPO," }, /* 0xe4 */
{ opout, "PUSH\tHL" }, /* 0xe5 */
{ nout, "AND\t" }, /* 0xe6 */
{ opout, "RST\t20" }, /* 0xe7 */
{ opout, "RET\tPE" }, /* 0xe8 */
{ opout, "JP\t(HL)" }, /* 0xe9 */
{ nnout, "JP\tPE," }, /* 0xea */
{ opout, "EX\tDE,HL" }, /* 0xeb */
{ nnout, "CALL\tPE," }, /* 0xec */
{ edop, "" }, /* 0xed */
{ nout, "XOR\t" }, /* 0xee */
{ opout, "RST\t28" }, /* 0xef */
{ opout, "RET\tP" }, /* 0xf0 */
{ opout, "POP\tAF" }, /* 0xf1 */
{ nnout, "JP\tP," }, /* 0xf2 */
{ opout, "DI" }, /* 0xf3 */
{ nnout, "CALL\tP," }, /* 0xf4 */
{ opout, "PUSH\tAF" }, /* 0xf5 */
{ nout, "OR\t" }, /* 0xf6 */
{ opout, "RST\t30" }, /* 0xf7 */
{ opout, "RET\tM" }, /* 0xf8 */
{ opout, "LD\tSP,HL" }, /* 0xf9 */
{ nnout, "JP\tM," }, /* 0xfa */
{ opout, "EI" }, /* 0xfb */
{ nnout, "CALL\tM," }, /* 0xfc */
{ ddfd, "" }, /* 0xfd */
{ nout, "CP\t" }, /* 0xfe */
{ opout, "RST\t38" } /* 0xff */
};
static int addr;
static char *unkown = "???";
static char *reg[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
static char *regix = "IX";
static char *regiy = "IY";
/*
* The function disass() is the only global function of
* this module. The first argument is a pointer to a
* unsigned char pointer, which points to the op-code
* to disassemble. The output of the disassembly goes
* to stdout, terminated by a newline. After the
* disassembly the pointer to the op-code will be
* increased by the size of the op-code, so that
* disass() can be called again.
* The secound argument is the (Z80) address of the
* op-code to disassemble. It is used to calculate the
* destination address of relative jumps.
*/
void disass(unsigned char **p, int adr)
{
register int len;
addr = adr;
len = (*optab[**p].fun) (optab[**p].text, p);
*p += len;
}
/*
* disassemble 1 byte op-codes
*/
static int opout(char *s, char **p)
{
puts(s);
return(1);
}
/*
* disassemble 2 byte op-codes of type "Op n"
*/
static int nout(char *s, unsigned char **p)
{
printf("%s%02x\n", s, *(*p + 1));
return(2);
}
/*
* disassemble 2 byte op-codes with indirect addressing
*/
static int iout(char *s, unsigned char **p)
{
printf(s, *(*p + 1));
putchar('\n');
return(2);
}
/*
* disassemble 2 byte op-codes with relative addressing
*/
static int rout(char *s, char **p)
{
printf("%s%04x\n", s, addr + *(*p + 1) + 2);
return(2);
}
/*
* disassemble 3 byte op-codes of type "Op nn"
*/
static int nnout(char *s, unsigned char **p)
{
register int i;
i = *(*p + 1) + (*(*p + 2) << 8);
printf("%s%04x\n", s, i);
return(3);
}
/*
* disassemble 3 byte op-codes with indirect addressing
*/
static int inout(char *s, unsigned char **p)
{
register int i;
i = *(*p + 1) + (*(*p + 2) << 8);
printf(s, i);
putchar('\n');
return(3);
}
/*
* disassemble multi byte op-codes with prefix 0xcb
*/
static int cbop(char *s, unsigned char **p)
{
register int b2;
b2 = *(*p + 1);
if (b2 >= 0x00 && b2 <= 0x07) {
printf("RLC\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x08 && b2 <= 0x0f) {
printf("RRC\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x10 && b2 <= 0x17) {
printf("RL\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x18 && b2 <= 0x1f) {
printf("RR\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x20 && b2 <= 0x27) {
printf("SLA\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x28 && b2 <= 0x2f) {
printf("SRA\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x38 && b2 <= 0x3f) {
printf("SRL\t");
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x40 && b2 <= 0x7f) {
printf("BIT\t");
printf("%c,", ((b2 >> 3) & 7) + '0');
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0x80 && b2 <= 0xbf) {
printf("RES\t");
printf("%c,", ((b2 >> 3) & 7) + '0');
printf("%s\n", reg[b2 & 7]);
return(2);
}
if (b2 >= 0xc0) {
printf("SET\t");
printf("%c,", ((b2 >> 3) & 7) + '0');
printf("%s\n", reg[b2 & 7]);
return(2);
}
puts(unkown);
return(2);
}
/*
* disassemble multi byte op-codes with prefix 0xed
*/
static int edop(char *s, unsigned char **p)
{
register int b2, i;
int len = 2;
b2 = *(*p + 1);
switch (b2) {
case 0x40:
puts("IN\tB,(C)");
break;
case 0x41:
puts("OUT\t(C),B");
break;
case 0x42:
puts("SBC\tHL,BC");
break;
case 0x43:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\t(%04x),BC\n", i);
len = 4;
break;
case 0x44:
puts("NEG");
break;
case 0x45:
puts("RETN");
break;
case 0x46:
puts("IM\t0");
break;
case 0x47:
puts("LD\tI,A");
break;
case 0x48:
puts("IN\tC,(C)");
break;
case 0x49:
puts("OUT\t(C),C");
break;
case 0x4a:
puts("ADC\tHL,BC");
break;
case 0x4b:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\tBC,(%04x)\n", i);
len = 4;
break;
case 0x4d:
puts("RETI");
break;
case 0x4f:
puts("LD\tR,A");
break;
case 0x50:
puts("IN\tD,(C)");
break;
case 0x51:
puts("OUT\t(C),D");
break;
case 0x52:
puts("SBC\tHL,DE");
break;
case 0x53:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\t(%04x),DE\n", i);
len = 4;
break;
case 0x56:
puts("IM\t1");
break;
case 0x57:
puts("LD\tA,I");
break;
case 0x58:
puts("IN\tE,(C)");
break;
case 0x59:
puts("OUT\t(C),E");
break;
case 0x5a:
puts("ADC\tHL,DE");
break;
case 0x5b:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\tDE,(%04x)\n", i);
len = 4;
break;
case 0x5e:
puts("IM\t2");
break;
case 0x5f:
puts("LD\tA,R");
break;
case 0x60:
puts("IN\tH,(C)");
break;
case 0x61:
puts("OUT\t(C),H");
break;
case 0x62:
puts("SBC\tHL,HL");
break;
case 0x67:
puts("RRD");
break;
case 0x68:
puts("IN\tL,(C)");
break;
case 0x69:
puts("OUT\t(C),L");
break;
case 0x6a:
puts("ADC\tHL,HL");
break;
case 0x6f:
puts("RLD");
break;
case 0x72:
puts("SBC\tHL,SP");
break;
case 0x73:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\t(%04x),SP\n", i);
len = 4;
break;
case 0x78:
puts("IN\tA,(C)");
break;
case 0x79:
puts("OUT\t(C),A");
break;
case 0x7a:
puts("ADC\tHL,SP");
break;
case 0x7b:
i = *(*p + 2) + (*(*p + 3) << 8);
printf("LD\tSP,(%04x)\n", i);
len = 4;
break;
case 0xa0:
puts("LDI");
break;
case 0xa1:
puts("CPI");
break;
case 0xa2:
puts("INI");
break;
case 0xa3:
puts("OUTI");
break;
case 0xa8:
puts("LDD");
break;
case 0xa9:
puts("CPD");
break;
case 0xaa:
puts("IND");
break;
case 0xab:
puts("OUTD");
break;
case 0xb0:
puts("LDIR");
break;
case 0xb1:
puts("CPIR");
break;
case 0xb2:
puts("INIR");
break;
case 0xb3:
puts("OTIR");
break;
case 0xb8:
puts("LDDR");
break;
case 0xb9:
puts("CPDR");
break;
case 0xba:
puts("INDR");
break;
case 0xbb:
puts("OTDR");
break;
default:
puts(unkown);
}
return(len);
}
/*
* disassemble multi byte op-codes with prefix 0xdd and 0xfd
*/
static int ddfd(char *s, unsigned char **p)
{
register int b2;
register char *ireg;
int len = 3;
if (**p == 0xdd)
ireg = regix;
else
ireg = regiy;
b2 = *(*p + 1);
if (b2 >= 0x70 && b2 <= 0x77) {
printf("LD\t(%s+%02x),%s\n", ireg, *(*p + 2), reg[b2 & 7]);
return(3);
}
switch (b2) {
case 0x09:
printf("ADD\t%s,BC\n", ireg);
len = 2;
break;
case 0x19:
printf("ADD\t%s,DE\n", ireg);
len = 2;
break;
case 0x21:
printf("LD\t%s,%04x\n", ireg, *(*p + 2) + (*(*p + 3) << 8));
len = 4;
break;
case 0x22:
printf("LD\t(%04x),%s\n", *(*p + 2) + (*(*p + 3) << 8), ireg);
len = 4;
break;
case 0x23:
printf("INC\t%s\n", ireg);
len = 2;
break;
case 0x29:
if (**p == 0xdd)
printf("ADD\tIX,IX\n");
else
printf("ADD\tIY,IY\n");
len = 2;
break;
case 0x2a:
printf("LD\t%s,(%04x)\n", ireg, *(*p + 2) + (*(*p + 3) << 8));
len = 4;
break;
case 0x2b:
printf("DEC\t%s\n", ireg);
len = 2;
break;
case 0x34:
printf("INC\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x35:
printf("DEC\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x36:
printf("LD\t(%s+%02x),%02x\n", ireg, *(*p + 2), *(*p + 3));
len = 4;
break;
case 0x39:
printf("ADD\t%s,SP\n", ireg);
len = 2;
break;
case 0x46:
printf("LD\tB,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x4e:
printf("LD\tC,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x56:
printf("LD\tD,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x5e:
printf("LD\tE,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x66:
printf("LD\tH,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x6e:
printf("LD\tL,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x7e:
printf("LD\tA,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x86:
printf("ADD\tA,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x8e:
printf("ADC\tA,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x96:
printf("SUB\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x9e:
printf("SBC\tA,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xa6:
printf("AND\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xae:
printf("XOR\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xb6:
printf("OR\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xbe:
printf("CP\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xcb:
switch (*(*p + 3)) {
case 0x06:
printf("RLC\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x0e:
printf("RRC\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x16:
printf("RL\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x1e:
printf("RR\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x26:
printf("SLA\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x2e:
printf("SRA\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x3e:
printf("SRL\t(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x46:
printf("BIT\t0,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x4e:
printf("BIT\t1,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x56:
printf("BIT\t2,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x5e:
printf("BIT\t3,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x66:
printf("BIT\t4,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x6e:
printf("BIT\t5,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x76:
printf("BIT\t6,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x7e:
printf("BIT\t7,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x86:
printf("RES\t0,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x8e:
printf("RES\t1,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x96:
printf("RES\t2,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0x9e:
printf("RES\t3,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xa6:
printf("RES\t4,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xae:
printf("RES\t5,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xb6:
printf("RES\t6,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xbe:
printf("RES\t7,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xc6:
printf("SET\t0,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xce:
printf("SET\t1,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xd6:
printf("SET\t2,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xde:
printf("SET\t3,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xe6:
printf("SET\t4,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xee:
printf("SET\t5,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xf6:
printf("SET\t6,(%s+%02x)\n", ireg, *(*p + 2));
break;
case 0xfe:
printf("SET\t7,(%s+%02x)\n", ireg, *(*p + 2));
break;
default:
puts(unkown);
}
len = 4;
break;
case 0xe1:
printf("POP\t%s\n", ireg);
len = 2;
break;
case 0xe3:
printf("EX\t(SP),%s\n", ireg);
len = 2;
break;
case 0xe5:
printf("PUSH\t%s\n", ireg);
len = 2;
break;
case 0xe9:
printf("JP\t(%s)\n", ireg);
len = 2;
break;
case 0xf9:
printf("LD\tSP,%s\n", ireg);
len = 2;
break;
default:
puts(unkown);
}
return(len);
}

Binary file not shown.

View File

@@ -0,0 +1,136 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* This modul of the simulator contains a simple terminal I/O
* simulation as an example.
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 03-OCT-06 Release 1.8 changed to ANSI C for modern POSIX OS's
*/
/*
* Sample I/O-handler
*
* Port 0 input: reads the next byte from stdin
* Port 0 output: writes the byte to stdout
*
* All the other ports are connected to a I/O-trap handler,
* I/O to this ports stops the simulation with an I/O error.
*/
#include <stdio.h>
#include "sim.h"
#include "simglb.h"
/*
* Forward declarations of the I/O functions
* for all port addresses.
*/
static BYTE io_trap(void);
static BYTE p000_in(void);
static void p000_out(BYTE);
/*
* This two dimensional array contains function pointers
* for every I/O port (0 - 255), to do the needed I/O.
* The first entry is for input, the second for output.
*/
static BYTE (*port[256][2]) () = {
{ p000_in, p000_out } /* port 0 */
};
/*
* This function is to initiate the I/O devices.
* It will be called from the CPU simulation before
* any operation with the Z80 is possible.
*
* In this sample I/O simulation we initialize all
* unused port with an error trap handler, so that
* simulation stops at I/O on the unused ports.
*
* See the I/O simulation of CP/M for a more complex
* example.
*/
void init_io(void)
{
register int i;
for (i = 1; i <= 255; i++)
port[i][0] = port[i][1] = io_trap;
}
/*
* This function is to stop the I/O devices. It is
* called from the CPU simulation on exit.
*
* Here is just nothing to do, see the I/O simulation
* of CP/M for a more complex example.
*/
void exit_io(void)
{
}
/*
* This is the main handler for all IN op-codes,
* called by the simulator. It calls the input
* function for port adr.
*/
BYTE io_in(BYTE adr)
{
return((*port[adr][0]) ());
}
/*
* This is the main handler for all OUT op-codes,
* called by the simulator. It calls the output
* function for port adr.
*/
void io_out(BYTE adr, BYTE data)
{
(*port[adr][1]) (data);
}
/*
* I/O trap funtion
* This function should be added into all unused
* entrys of the port array. It stops the emulation
* with an I/O error.
*/
static BYTE io_trap(void)
{
if (i_flag) {
cpu_error = IOTRAP;
cpu_state = STOPPED;
}
return((BYTE) 0);
}
/*
* I/O function port 0 read:
* Read next byte from stdin.
*/
static BYTE p000_in(void)
{
return((BYTE) getchar());
}
/*
* I/O function port 0 write:
* Write byte to stdout and flush the output.
*/
static void p000_out(BYTE data)
{
putchar((int) data);
fflush(stdout);
}

Binary file not shown.

2
emu/z80pack-1.9/z80sim/run.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
./z80sim

View File

@@ -0,0 +1,104 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* This is the configuration I'm using for software testing and debugging
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* The following defines may be activated, commented or modified
* by user for her/his own purpose.
*/
/*#define WANT_INT*/ /* activate CPU's interrupts */
#define WANT_SPC /* activate SP over-/underrun handling 0000<->FFFF */
#define WANT_PCC /* activate PC overrun handling FFFF->0000 */
#define CNTL_C /* cntl-c will stop running emulation */
#define CNTL_BS /* cntl-\ will stop running emulation */
#define CNTL_Z /* cntl-z will suspend emulator */
#define WANT_TIM /* activate runtime measurement */
#define HISIZE 100 /* number of entrys in history */
#define SBSIZE 4 /* number of software breakpoints */
/*
* The following defines may be modified and activated by
* user, to print her/his copyright for a developed system,
* which contains the Z80-CPU simulation as a part.
*/
/*
#define USR_COM "XYZ-System Simulation"
#define USR_REL "x.y"
#define USR_CPR "Copyright (C) 20xx by XYZ"
*/
/*
* The following lines of this file should not be modified by user
*/
#define COPYR "Copyright (C) 1987-2006 by Udo Munk"
#define RELEASE "1.9"
#define LENCMD 80 /* length of command buffers etc */
#define S_FLAG 128 /* bit definitions of CPU flags */
#define Z_FLAG 64
#define N2_FLAG 32
#define H_FLAG 16
#define N1_FLAG 8
#define P_FLAG 4
#define N_FLAG 2
#define C_FLAG 1
/* operation of simulated CPU */
#define SINGLE_STEP 0 /* single step */
#define CONTIN_RUN 1 /* continual run */
#define STOPPED 0 /* stop CPU because of error */
/* causes of error */
#define NONE 0 /* no error */
#define OPHALT 1 /* HALT op-code trap */
#define IOTRAP 2 /* IN/OUT trap */
#define OPTRAP1 3 /* illegal 1 byte op-code trap */
#define OPTRAP2 4 /* illegal 2 byte op-code trap */
#define OPTRAP4 5 /* illegal 4 byte op-code trap */
#define USERINT 6 /* user interrupt */
/* type of CPU interrupt */
#define INT_NMI 1 /* non maskable interrupt */
#define INT_INT 2 /* maskable interrupt */
typedef unsigned short WORD; /* 16 bit unsigned */
typedef unsigned char BYTE; /* 8 bit unsigned */
#ifdef HISIZE
struct history { /* structure of a history entry */
WORD h_adr; /* address of execution */
WORD h_af; /* register AF */
WORD h_bc; /* register BC */
WORD h_de; /* register DE */
WORD h_hl; /* register HL */
WORD h_ix; /* register IX */
WORD h_iy; /* register IY */
WORD h_sp; /* register SP */
};
#endif
#ifdef SBSIZE
struct softbreak { /* structure of a breakpoint */
WORD sb_adr; /* address of breakpoint */
BYTE sb_oldopc; /* op-code at address of breakpoint */
int sb_passcount; /* pass counter of breakpoint */
int sb_pass; /* no. of pass to break */
};
#endif

View File

@@ -0,0 +1,104 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* This is the configuration I'm using for software testing and debugging
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* The following defines may be activated, commented or modified
* by user for her/his own purpose.
*/
/*#define WANT_INT*/ /* activate CPU's interrupts */
#define WANT_SPC /* activate SP over-/underrun handling 0000<->FFFF */
#define WANT_PCC /* activate PC overrun handling FFFF->0000 */
#define CNTL_C /* cntl-c will stop running emulation */
#define CNTL_BS /* cntl-\ will stop running emulation */
#define CNTL_Z /* cntl-z will suspend emulator */
#define WANT_TIM /* activate runtime measurement */
#define HISIZE 100 /* number of entrys in history */
#define SBSIZE 4 /* number of software breakpoints */
/*
* The following defines may be modified and activated by
* user, to print her/his copyright for a developed system,
* which contains the Z80-CPU simulation as a part.
*/
/*
#define USR_COM "XYZ-System Simulation"
#define USR_REL "x.y"
#define USR_CPR "Copyright (C) 20xx by XYZ"
*/
/*
* The following lines of this file should not be modified by user
*/
#define COPYR "Copyright (C) 1987-2006 by Udo Munk"
#define RELEASE "1.9"
#define LENCMD 80 /* length of command buffers etc */
#define S_FLAG 128 /* bit definitions of CPU flags */
#define Z_FLAG 64
#define N2_FLAG 32
#define H_FLAG 16
#define N1_FLAG 8
#define P_FLAG 4
#define N_FLAG 2
#define C_FLAG 1
/* operation of simulated CPU */
#define SINGLE_STEP 0 /* single step */
#define CONTIN_RUN 1 /* continual run */
#define STOPPED 0 /* stop CPU because of error */
/* causes of error */
#define NONE 0 /* no error */
#define OPHALT 1 /* HALT op-code trap */
#define IOTRAP 2 /* IN/OUT trap */
#define OPTRAP1 3 /* illegal 1 byte op-code trap */
#define OPTRAP2 4 /* illegal 2 byte op-code trap */
#define OPTRAP4 5 /* illegal 4 byte op-code trap */
#define USERINT 6 /* user interrupt */
/* type of CPU interrupt */
#define INT_NMI 1 /* non maskable interrupt */
#define INT_INT 2 /* maskable interrupt */
typedef unsigned short WORD; /* 16 bit unsigned */
typedef unsigned char BYTE; /* 8 bit unsigned */
#ifdef HISIZE
struct history { /* structure of a history entry */
WORD h_adr; /* address of execution */
WORD h_af; /* register AF */
WORD h_bc; /* register BC */
WORD h_de; /* register DE */
WORD h_hl; /* register HL */
WORD h_ix; /* register IX */
WORD h_iy; /* register IY */
WORD h_sp; /* register SP */
};
#endif
#ifdef SBSIZE
struct softbreak { /* structure of a breakpoint */
WORD sb_adr; /* address of breakpoint */
BYTE sb_oldopc; /* op-code at address of breakpoint */
int sb_passcount; /* pass counter of breakpoint */
int sb_pass; /* no. of pass to break */
};
#endif

View File

@@ -0,0 +1,106 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* With this configuration the simulated Z80 runs with the
* highest possible speed
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* The following defines may be activated, commented or modified
* by user for her/his own purpose.
*/
/*#define WANT_INT*/ /* activate CPU's interrupts */
/*#define WANT_SPC*/ /* activate SP over-/underrun handling 0000<->FFFF */
/*#define WANT_PCC*/ /* activate PC overrun handling FFFF->0000 */
#define CNTL_C /* cntl-c will stop running emulation */
#define CNTL_BS /* cntl-\ will stop running emulation */
#define CNTL_Z /* cntl-z will suspend emulator */
/*#define WANT_TIM*/ /* activate runtime measurement */
/*#define HISIZE 100*/ /* number of entrys in history */
/*#define SBSIZE 4*/ /* number of software breakpoints */
/*
* The following defines may be modified and activated by
* user, to print her/his copyright for a developed system,
* which contains the Z80-CPU simulation as a part.
*/
/*
#define USR_COM "XYZ-System Simulation"
#define USR_REL "x.y"
#define USR_CPR "Copyright (C) 20xx by XYZ"
*/
/*
* The following lines of this file should not be modified by user
*/
#define COPYR "Copyright (C) 1987-2006 by Udo Munk"
#define RELEASE "1.9"
#define LENCMD 80 /* length of command buffers etc */
#define S_FLAG 128 /* bit definitions of CPU flags */
#define Z_FLAG 64
#define N2_FLAG 32
#define H_FLAG 16
#define N1_FLAG 8
#define P_FLAG 4
#define N_FLAG 2
#define C_FLAG 1
/* operation of simulated CPU */
#define SINGLE_STEP 0 /* single step */
#define CONTIN_RUN 1 /* continual run */
#define STOPPED 0 /* stop CPU because of error */
/* causes of error */
#define NONE 0 /* no error */
#define OPHALT 1 /* HALT op-code trap */
#define IOTRAP 2 /* IN/OUT trap */
#define OPTRAP1 3 /* illegal 1 byte op-code trap */
#define OPTRAP2 4 /* illegal 2 byte op-code trap */
#define OPTRAP4 5 /* illegal 4 byte op-code trap */
#define USERINT 6 /* user interrupt */
/* type of CPU interrupt */
#define INT_NONE 0
#define INT_NMI 1 /* non maskable interrupt */
#define INT_INT 2 /* maskable interrupt */
typedef unsigned short WORD; /* 16 bit unsigned */
typedef unsigned char BYTE; /* 8 bit unsigned */
#ifdef HISIZE
struct history { /* structure of a history entry */
WORD h_adr; /* address of execution */
WORD h_af; /* register AF */
WORD h_bc; /* register BC */
WORD h_de; /* register DE */
WORD h_hl; /* register HL */
WORD h_ix; /* register IX */
WORD h_iy; /* register IY */
WORD h_sp; /* register SP */
};
#endif
#ifdef SBSIZE
struct softbreak { /* structure of a breakpoint */
WORD sb_adr; /* address of breakpoint */
BYTE sb_oldopc; /* op-code at address of breakpoint */
int sb_passcount; /* pass counter of breakpoint */
int sb_pass; /* no. of pass to break */
};
#endif

View File

@@ -0,0 +1,202 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0
* 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* This modul contain the 'main()' function of the simulator,
* where the options are checked and variables are initialized.
* After initialization of the UNIX interrupts ( int_on() )
* and initialization of the I/O simulation ( init_io() )
* the user interface ( mon() ) is called.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <memory.h>
#include "sim.h"
#include "simglb.h"
static void save_core(void), load_core(void);
extern void int_on(void), int_off(void), mon(void);
extern void init_io(void), exit_io(void);
extern int exatoi(char *);
int main(int argc, char *argv[])
{
register char *s, *p;
register char *pn = argv[0];
while (--argc > 0 && (*++argv)[0] == '-')
for (s = argv[0] + 1; *s != '\0'; s++)
switch (*s) {
case 's': /* save core and CPU on exit */
s_flag = 1;
break;
case 'l': /* load core and CPU from file */
l_flag = 1;
break;
case 'h': /* execute HALT opcode */
break_flag = 0;
break;
case 'i': /* trap I/O on unused ports */
i_flag = 1;
break;
case 'm': /* initialize Z80 memory */
m_flag = exatoi(s+1);
s += strlen(s+1);
break;
case 'f':
f_flag = atoi(s+1);
s += strlen(s+1);
freq = (float) 1 / (float) f_flag;
break;
case 'x': /* get filename with Z80 executable */
x_flag = 1;
s++;
p = xfn;
while (*s)
*p++ = *s++;
*p = '\0';
s--;
break;
case '?':
goto usage;
default:
printf("illegal option %c\n", *s);
usage: printf("usage:\t%s -s -l -i -h -mn -fn -xfilename\n", pn);
puts("\ts = save core and cpu");
puts("\tl = load core and cpu");
puts("\ti = trap on I/O to unused ports");
puts("\th = execute HALT op-code");
puts("\tm = init memory with n");
puts("\tf = CPU frequenzy n in MHz (not implemented yet)");
puts("\tx = load and execute filename");
exit(1);
}
putchar('\n');
puts("####### ##### ### ##### ### # #");
puts(" # # # # # # # # ## ##");
puts(" # # # # # # # # # # #");
puts(" # ##### # # ##### ##### # # # #");
puts(" # # # # # # # # #");
puts(" # # # # # # # # # #");
puts("####### ##### ### ##### ### # #");
printf("\nRelease %s, %s\n", RELEASE, COPYR);
#ifdef USR_COM
printf("%s Release %s, %s\n", USR_COM, USR_REL, USR_CPR);
#endif
putchar('\n');
fflush(stdout);
wrk_ram = PC = STACK = ram;
memset((char *) ram, m_flag, 32768);
memset((char *) ram + 32768, m_flag, 32768);
if (l_flag)
load_core();
int_on();
init_io();
mon();
if (s_flag)
save_core();
exit_io();
int_off();
return(0);
}
/*
* This function saves the CPU and the memory into the file core.z80
*
*/
static void save_core(void)
{
int fd;
if ((fd = open("core.z80", O_WRONLY | O_CREAT, 0600)) == -1) {
puts("can't open file core.z80");
return;
}
write(fd, (char *) &A, sizeof(A));
write(fd, (char *) &F, sizeof(F));
write(fd, (char *) &B, sizeof(B));
write(fd, (char *) &C, sizeof(C));
write(fd, (char *) &D, sizeof(D));
write(fd, (char *) &E, sizeof(E));
write(fd, (char *) &H, sizeof(H));
write(fd, (char *) &L, sizeof(L));
write(fd, (char *) &A_, sizeof(A_));
write(fd, (char *) &F_, sizeof(F_));
write(fd, (char *) &B_, sizeof(B_));
write(fd, (char *) &C_, sizeof(C_));
write(fd, (char *) &D_, sizeof(D_));
write(fd, (char *) &E_, sizeof(E_));
write(fd, (char *) &H_, sizeof(H_));
write(fd, (char *) &L_, sizeof(L_));
write(fd, (char *) &I, sizeof(I));
write(fd, (char *) &IFF, sizeof(IFF));
write(fd, (char *) &R, sizeof(R));
write(fd, (char *) &PC, sizeof(PC));
write(fd, (char *) &STACK, sizeof(STACK));
write(fd, (char *) &IX, sizeof(IX));
write(fd, (char *) &IY, sizeof(IY));
write(fd, (char *) ram, 32768);
write(fd, (char *) ram + 32768, 32768);
close(fd);
}
/*
* This function loads the CPU and memory from the file core.z80
*
*/
static void load_core(void)
{
int fd;
if ((fd = open("core.z80", O_RDONLY)) == -1) {
puts("can't open file core.z80");
return;
}
read(fd, (char *) &A, sizeof(A));
read(fd, (char *) &F, sizeof(F));
read(fd, (char *) &B, sizeof(B));
read(fd, (char *) &C, sizeof(C));
read(fd, (char *) &D, sizeof(D));
read(fd, (char *) &E, sizeof(E));
read(fd, (char *) &H, sizeof(H));
read(fd, (char *) &L, sizeof(L));
read(fd, (char *) &A_, sizeof(A_));
read(fd, (char *) &F_, sizeof(F_));
read(fd, (char *) &B_, sizeof(B_));
read(fd, (char *) &C_, sizeof(C_));
read(fd, (char *) &D_, sizeof(D_));
read(fd, (char *) &E_, sizeof(E_));
read(fd, (char *) &H_, sizeof(H_));
read(fd, (char *) &L_, sizeof(L_));
read(fd, (char *) &I, sizeof(I));
read(fd, (char *) &IFF, sizeof(IFF));
read(fd, (char *) &R, sizeof(R));
read(fd, (char *) &PC, sizeof(PC));
read(fd, (char *) &STACK, sizeof(STACK));
read(fd, (char *) &IX, sizeof(IX));
read(fd, (char *) &IY, sizeof(IY));
read(fd, (char *) ram, 32768);
read(fd, (char *) ram + 32768, 32768);
close(fd);
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,727 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* Like the function "cpu()" this one emulates multi byte opcodes
* starting with 0xdd
*/
#include "sim.h"
#include "simglb.h"
static int trap_dd(void);
static int op_popix(void), op_pusix(void);
static int op_jpix(void);
static int op_exspx(void);
static int op_ldspx(void);
static int op_ldixnn(void), op_ldixinn(void), op_ldinx(void);
static int op_adaxd(void), op_acaxd(void), op_suaxd(void), op_scaxd(void);
static int op_andxd(void), op_xorxd(void), op_orxd(void), op_cpxd(void);
static int op_decxd(void), op_incxd(void);
static int op_addxb(void), op_addxd(void), op_addxs(void), op_addxx();
static int op_incix(void), op_decix(void);
static int op_ldaxd(void), op_ldbxd(void), op_ldcxd(void);
static int op_lddxd(), op_ldexd(void);
static int op_ldhxd(void), op_ldlxd(void);
static int op_ldxda(void), op_ldxdb(void), op_ldxdc(void);
static int op_ldxdd(), op_ldxde(void);
static int op_ldxdh(void), op_ldxdl(void), op_ldxdn(void);
extern int op_ddcb_handel(void);
long op_dd_handel(void)
{
register int t;
static int (*op_dd[256]) (void) = {
trap_dd, /* 0x00 */
trap_dd, /* 0x01 */
trap_dd, /* 0x02 */
trap_dd, /* 0x03 */
trap_dd, /* 0x04 */
trap_dd, /* 0x05 */
trap_dd, /* 0x06 */
trap_dd, /* 0x07 */
trap_dd, /* 0x08 */
op_addxb, /* 0x09 */
trap_dd, /* 0x0a */
trap_dd, /* 0x0b */
trap_dd, /* 0x0c */
trap_dd, /* 0x0d */
trap_dd, /* 0x0e */
trap_dd, /* 0x0f */
trap_dd, /* 0x10 */
trap_dd, /* 0x11 */
trap_dd, /* 0x12 */
trap_dd, /* 0x13 */
trap_dd, /* 0x14 */
trap_dd, /* 0x15 */
trap_dd, /* 0x16 */
trap_dd, /* 0x17 */
trap_dd, /* 0x18 */
op_addxd, /* 0x19 */
trap_dd, /* 0x1a */
trap_dd, /* 0x1b */
trap_dd, /* 0x1c */
trap_dd, /* 0x1d */
trap_dd, /* 0x1e */
trap_dd, /* 0x1f */
trap_dd, /* 0x20 */
op_ldixnn, /* 0x21 */
op_ldinx, /* 0x22 */
op_incix, /* 0x23 */
trap_dd, /* 0x24 */
trap_dd, /* 0x25 */
trap_dd, /* 0x26 */
trap_dd, /* 0x27 */
trap_dd, /* 0x28 */
op_addxx, /* 0x29 */
op_ldixinn, /* 0x2a */
op_decix, /* 0x2b */
trap_dd, /* 0x2c */
trap_dd, /* 0x2d */
trap_dd, /* 0x2e */
trap_dd, /* 0x2f */
trap_dd, /* 0x30 */
trap_dd, /* 0x31 */
trap_dd, /* 0x32 */
trap_dd, /* 0x33 */
op_incxd, /* 0x34 */
op_decxd, /* 0x35 */
op_ldxdn, /* 0x36 */
trap_dd, /* 0x37 */
trap_dd, /* 0x38 */
op_addxs, /* 0x39 */
trap_dd, /* 0x3a */
trap_dd, /* 0x3b */
trap_dd, /* 0x3c */
trap_dd, /* 0x3d */
trap_dd, /* 0x3e */
trap_dd, /* 0x3f */
trap_dd, /* 0x40 */
trap_dd, /* 0x41 */
trap_dd, /* 0x42 */
trap_dd, /* 0x43 */
trap_dd, /* 0x44 */
trap_dd, /* 0x45 */
op_ldbxd, /* 0x46 */
trap_dd, /* 0x47 */
trap_dd, /* 0x48 */
trap_dd, /* 0x49 */
trap_dd, /* 0x4a */
trap_dd, /* 0x4b */
trap_dd, /* 0x4c */
trap_dd, /* 0x4d */
op_ldcxd, /* 0x4e */
trap_dd, /* 0x4f */
trap_dd, /* 0x50 */
trap_dd, /* 0x51 */
trap_dd, /* 0x52 */
trap_dd, /* 0x53 */
trap_dd, /* 0x54 */
trap_dd, /* 0x55 */
op_lddxd, /* 0x56 */
trap_dd, /* 0x57 */
trap_dd, /* 0x58 */
trap_dd, /* 0x59 */
trap_dd, /* 0x5a */
trap_dd, /* 0x5b */
trap_dd, /* 0x5c */
trap_dd, /* 0x5d */
op_ldexd, /* 0x5e */
trap_dd, /* 0x5f */
trap_dd, /* 0x60 */
trap_dd, /* 0x61 */
trap_dd, /* 0x62 */
trap_dd, /* 0x63 */
trap_dd, /* 0x64 */
trap_dd, /* 0x65 */
op_ldhxd, /* 0x66 */
trap_dd, /* 0x67 */
trap_dd, /* 0x68 */
trap_dd, /* 0x69 */
trap_dd, /* 0x6a */
trap_dd, /* 0x6b */
trap_dd, /* 0x6c */
trap_dd, /* 0x6d */
op_ldlxd, /* 0x6e */
trap_dd, /* 0x6f */
op_ldxdb, /* 0x70 */
op_ldxdc, /* 0x71 */
op_ldxdd, /* 0x72 */
op_ldxde, /* 0x73 */
op_ldxdh, /* 0x74 */
op_ldxdl, /* 0x75 */
trap_dd, /* 0x76 */
op_ldxda, /* 0x77 */
trap_dd, /* 0x78 */
trap_dd, /* 0x79 */
trap_dd, /* 0x7a */
trap_dd, /* 0x7b */
trap_dd, /* 0x7c */
trap_dd, /* 0x7d */
op_ldaxd, /* 0x7e */
trap_dd, /* 0x7f */
trap_dd, /* 0x80 */
trap_dd, /* 0x81 */
trap_dd, /* 0x82 */
trap_dd, /* 0x83 */
trap_dd, /* 0x84 */
trap_dd, /* 0x85 */
op_adaxd, /* 0x86 */
trap_dd, /* 0x87 */
trap_dd, /* 0x88 */
trap_dd, /* 0x89 */
trap_dd, /* 0x8a */
trap_dd, /* 0x8b */
trap_dd, /* 0x8c */
trap_dd, /* 0x8d */
op_acaxd, /* 0x8e */
trap_dd, /* 0x8f */
trap_dd, /* 0x90 */
trap_dd, /* 0x91 */
trap_dd, /* 0x92 */
trap_dd, /* 0x93 */
trap_dd, /* 0x94 */
trap_dd, /* 0x95 */
op_suaxd, /* 0x96 */
trap_dd, /* 0x97 */
trap_dd, /* 0x98 */
trap_dd, /* 0x99 */
trap_dd, /* 0x9a */
trap_dd, /* 0x9b */
trap_dd, /* 0x9c */
trap_dd, /* 0x9d */
op_scaxd, /* 0x9e */
trap_dd, /* 0x9f */
trap_dd, /* 0xa0 */
trap_dd, /* 0xa1 */
trap_dd, /* 0xa2 */
trap_dd, /* 0xa3 */
trap_dd, /* 0xa4 */
trap_dd, /* 0xa5 */
op_andxd, /* 0xa6 */
trap_dd, /* 0xa7 */
trap_dd, /* 0xa8 */
trap_dd, /* 0xa9 */
trap_dd, /* 0xaa */
trap_dd, /* 0xab */
trap_dd, /* 0xac */
trap_dd, /* 0xad */
op_xorxd, /* 0xae */
trap_dd, /* 0xaf */
trap_dd, /* 0xb0 */
trap_dd, /* 0xb1 */
trap_dd, /* 0xb2 */
trap_dd, /* 0xb3 */
trap_dd, /* 0xb4 */
trap_dd, /* 0xb5 */
op_orxd, /* 0xb6 */
trap_dd, /* 0xb7 */
trap_dd, /* 0xb8 */
trap_dd, /* 0xb9 */
trap_dd, /* 0xba */
trap_dd, /* 0xbb */
trap_dd, /* 0xbc */
trap_dd, /* 0xbd */
op_cpxd, /* 0xbe */
trap_dd, /* 0xbf */
trap_dd, /* 0xc0 */
trap_dd, /* 0xc1 */
trap_dd, /* 0xc2 */
trap_dd, /* 0xc3 */
trap_dd, /* 0xc4 */
trap_dd, /* 0xc5 */
trap_dd, /* 0xc6 */
trap_dd, /* 0xc7 */
trap_dd, /* 0xc8 */
trap_dd, /* 0xc9 */
trap_dd, /* 0xca */
op_ddcb_handel, /* 0xcb */
trap_dd, /* 0xcc */
trap_dd, /* 0xcd */
trap_dd, /* 0xce */
trap_dd, /* 0xcf */
trap_dd, /* 0xd0 */
trap_dd, /* 0xd1 */
trap_dd, /* 0xd2 */
trap_dd, /* 0xd3 */
trap_dd, /* 0xd4 */
trap_dd, /* 0xd5 */
trap_dd, /* 0xd6 */
trap_dd, /* 0xd7 */
trap_dd, /* 0xd8 */
trap_dd, /* 0xd9 */
trap_dd, /* 0xda */
trap_dd, /* 0xdb */
trap_dd, /* 0xdc */
trap_dd, /* 0xdd */
trap_dd, /* 0xde */
trap_dd, /* 0xdf */
trap_dd, /* 0xe0 */
op_popix, /* 0xe1 */
trap_dd, /* 0xe2 */
op_exspx, /* 0xe3 */
trap_dd, /* 0xe4 */
op_pusix, /* 0xe5 */
trap_dd, /* 0xe6 */
trap_dd, /* 0xe7 */
trap_dd, /* 0xe8 */
op_jpix, /* 0xe9 */
trap_dd, /* 0xea */
trap_dd, /* 0xeb */
trap_dd, /* 0xec */
trap_dd, /* 0xed */
trap_dd, /* 0xee */
trap_dd, /* 0xef */
trap_dd, /* 0xf0 */
trap_dd, /* 0xf1 */
trap_dd, /* 0xf2 */
trap_dd, /* 0xf3 */
trap_dd, /* 0xf4 */
trap_dd, /* 0xf5 */
trap_dd, /* 0xf6 */
trap_dd, /* 0xf7 */
trap_dd, /* 0xf8 */
op_ldspx, /* 0xf9 */
trap_dd, /* 0xfa */
trap_dd, /* 0xfb */
trap_dd, /* 0xfc */
trap_dd, /* 0xfd */
trap_dd, /* 0xfe */
trap_dd /* 0xff */
};
#ifdef WANT_TIM
t = (*op_dd[*PC++]) (); /* execute next opcode */
#else
(*op_dd[*PC++]) ();
#endif
#ifdef WANT_PCC
if (PC > ram + 65535) /* correct PC overrun */
PC = ram;
#endif
return(t);
}
/*
* This function traps all illegal opcodes following the
* initial 0xdd of a multi byte opcode.
*/
static int trap_dd(void)
{
cpu_error = OPTRAP2;
cpu_state = STOPPED;
return(0);
}
static int op_popix(void) /* POP IX */
{
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
IX = *STACK++;
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
IX += *STACK++ << 8;
return(14);
}
static int op_pusix(void) /* PUSH IX */
{
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
*--STACK = IX >> 8;
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
*--STACK = IX;
return(15);
}
static int op_jpix(void) /* JP (IX) */
{
PC = ram + IX;
return(8);
}
static int op_exspx(void) /* EX (SP),IX */
{
register int i;
i = *STACK + (*(STACK + 1) << 8);
*STACK = IX;
*(STACK + 1) = IX >> 8;
IX = i;
return(23);
}
static int op_ldspx(void) /* LD SP,IX */
{
STACK = ram + IX;
return(10);
}
static int op_ldixnn(void) /* LD IX,nn */
{
IX = *PC++;
IX += *PC++ << 8;
return(14);
}
static int op_ldixinn(void) /* LD IX,(nn) */
{
register BYTE *p;
p = ram + *PC++;
p += *PC++ << 8;
IX = *p++;
IX += *p << 8;
return(20);
}
static int op_ldinx(void) /* LD (nn),IX */
{
register BYTE *p;
p = ram + *PC++;
p += *PC++ << 8;
*p++ = IX;
*p = IX >> 8;
return(20);
}
static int op_adaxd(void) /* ADD A,(IX+d) */
{
register int i;
register BYTE P;
P = *(ram + IX + (char) *PC++);
((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A + (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(19);
}
static int op_acaxd(void) /* ADC A,(IX+d) */
{
register int i, carry;
register BYTE P;
carry = (F & C_FLAG) ? 1 : 0;
P = *(ram + IX + (char) *PC++);
((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A + (char) P + carry;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(19);
}
static int op_suaxd(void) /* SUB A,(IX+d) */
{
register int i;
register BYTE P;
P = *(ram + IX + (char) *PC++);
((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A - (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_scaxd(void) /* SBC A,(IX+d) */
{
register int i, carry;
register BYTE P;
carry = (F & C_FLAG) ? 1 : 0;
P = *(ram + IX + (char) *PC++);
((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A - (char) P - carry;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_andxd(void) /* AND (IX+d) */
{
A &= *(ram + IX + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= H_FLAG;
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(N_FLAG | C_FLAG);
return(19);
}
static int op_xorxd(void) /* XOR (IX+d) */
{
A ^= *(ram + IX + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(H_FLAG | N_FLAG | C_FLAG);
return(19);
}
static int op_orxd(void) /* OR (IX+d) */
{
A |= *(ram + IX + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(H_FLAG | N_FLAG | C_FLAG);
return(19);
}
static int op_cpxd(void) /* CP (IX+d) */
{
register int i;
register BYTE P;
P = *(ram + IX + (char) *PC++);
((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
i = (char) A - (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_incxd(void) /* INC (IX+d) */
{
register BYTE *p;
p = ram + IX + (char) *PC++;
((*p & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(*p)++;
(*p == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(23);
}
static int op_decxd(void) /* DEC (IX+d) */
{
register BYTE *p;
p = ram + IX + (char) *PC++;
(((*p - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(*p)--;
(*p == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(23);
}
static int op_addxb(void) /* ADD IX,BC */
{
register int carry;
BYTE ixl = IX & 0xff;
BYTE ixh = IX >> 8;
carry = (ixl + C > 255) ? 1 : 0;
ixl += C;
((ixh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(ixh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
ixh += B + carry;
IX = (ixh << 8) + ixl;
F &= ~N_FLAG;
return(15);
}
static int op_addxd(void) /* ADD IX,DE */
{
register int carry;
BYTE ixl = IX & 0xff;
BYTE ixh = IX >> 8;
carry = (ixl + E > 255) ? 1 : 0;
ixl += E;
((ixh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(ixh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
ixh += D + carry;
IX = (ixh << 8) + ixl;
F &= ~N_FLAG;
return(15);
}
static int op_addxs(void) /* ADD IX,SP */
{
register int carry;
BYTE ixl = IX & 0xff;
BYTE ixh = IX >> 8;
BYTE spl = (STACK - ram) & 0xff;
BYTE sph = (STACK - ram) >> 8;
carry = (ixl + spl > 255) ? 1 : 0;
ixl += spl;
((ixh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(ixh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
ixh += sph + carry;
IX = (ixh << 8) + ixl;
F &= ~N_FLAG;
return(15);
}
static int op_addxx(void) /* ADD IX,IX */
{
register int carry;
BYTE ixl = IX & 0xff;
BYTE ixh = IX >> 8;
carry = (ixl << 1 > 255) ? 1 : 0;
ixl <<= 1;
((ixh & 0xf) + (ixh & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(ixh + ixh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
ixh += ixh + carry;
IX = (ixh << 8) + ixl;
F &= ~N_FLAG;
return(15);
}
static int op_incix(void) /* INC IX */
{
IX++;
return(10);
}
static int op_decix(void) /* DEC IX */
{
IX--;
return(10);
}
static int op_ldaxd(void) /* LD A,(IX+d) */
{
A = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldbxd(void) /* LD B,(IX+d) */
{
B = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldcxd(void) /* LD C,(IX+d) */
{
C = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_lddxd(void) /* LD D,(IX+d) */
{
D = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldexd(void) /* LD E,(IX+d) */
{
E = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldhxd(void) /* LD H,(IX+d) */
{
H = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldlxd(void) /* LD L,(IX+d) */
{
L = *(IX + (char) *PC++ + ram);
return(19);
}
static int op_ldxda(void) /* LD (IX+d),A */
{
*(IX + (char) *PC++ + ram) = A;
return(19);
}
static int op_ldxdb(void) /* LD (IX+d),B */
{
*(IX + (char) *PC++ + ram) = B;
return(19);
}
static int op_ldxdc(void) /* LD (IX+d),C */
{
*(IX + (char) *PC++ + ram) = C;
return(19);
}
static int op_ldxdd(void) /* LD (IX+d),D */
{
*(IX + (char) *PC++ + ram) = D;
return(19);
}
static int op_ldxde(void) /* LD (IX+d),E */
{
*(IX + (char) *PC++ + ram) = E;
return(19);
}
static int op_ldxdh(void) /* LD (IX+d),H */
{
*(IX + (char) *PC++ + ram) = H;
return(19);
}
static int op_ldxdl(void) /* LD (IX+d),L */
{
*(IX + (char) *PC++ + ram) = L;
return(19);
}
static int op_ldxdn(void) /* LD (IX+d),n */
{
register int d;
d = (char) *PC++;
*(IX + d + ram) = *PC++;
return(19);
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,728 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* Like the function "cpu()" this one emulates multi byte opcodes
* starting with 0xfd
*/
#include "sim.h"
#include "simglb.h"
static int trap_fd(void);
static int op_popiy(void), op_pusiy(void);
static int op_jpiy(void);
static int op_exspy(void);
static int op_ldspy(void);
static int op_ldiynn(void), op_ldiyinn(void), op_ldiny(void);
static int op_adayd(void), op_acayd(void), op_suayd(void), op_scayd(void);
static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void);
static int op_decyd(void), op_incyd(void);
static int op_addyb(void), op_addyd(void), op_addys(void), op_addyy(void);
static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void);
static int op_decyd(void), op_incyd(void);
static int op_inciy(void), op_deciy(void);
static int op_ldayd(void), op_ldbyd(void), op_ldcyd(void);
static int op_lddyd(void), op_ldeyd(void);
static int op_ldhyd(void), op_ldlyd(void);
static int op_ldyda(void), op_ldydb(void), op_ldydc(void);
static int op_ldydd(void), op_ldyde(void);
static int op_ldydh(void), op_ldydl(void), op_ldydn(void);
extern int op_fdcb_handel(void);
int op_fd_handel(void)
{
register int t;
static int (*op_fd[256]) () = {
trap_fd, /* 0x00 */
trap_fd, /* 0x01 */
trap_fd, /* 0x02 */
trap_fd, /* 0x03 */
trap_fd, /* 0x04 */
trap_fd, /* 0x05 */
trap_fd, /* 0x06 */
trap_fd, /* 0x07 */
trap_fd, /* 0x08 */
op_addyb, /* 0x09 */
trap_fd, /* 0x0a */
trap_fd, /* 0x0b */
trap_fd, /* 0x0c */
trap_fd, /* 0x0d */
trap_fd, /* 0x0e */
trap_fd, /* 0x0f */
trap_fd, /* 0x10 */
trap_fd, /* 0x11 */
trap_fd, /* 0x12 */
trap_fd, /* 0x13 */
trap_fd, /* 0x14 */
trap_fd, /* 0x15 */
trap_fd, /* 0x16 */
trap_fd, /* 0x17 */
trap_fd, /* 0x18 */
op_addyd, /* 0x19 */
trap_fd, /* 0x1a */
trap_fd, /* 0x1b */
trap_fd, /* 0x1c */
trap_fd, /* 0x1d */
trap_fd, /* 0x1e */
trap_fd, /* 0x1f */
trap_fd, /* 0x20 */
op_ldiynn, /* 0x21 */
op_ldiny, /* 0x22 */
op_inciy, /* 0x23 */
trap_fd, /* 0x24 */
trap_fd, /* 0x25 */
trap_fd, /* 0x26 */
trap_fd, /* 0x27 */
trap_fd, /* 0x28 */
op_addyy, /* 0x29 */
op_ldiyinn, /* 0x2a */
op_deciy, /* 0x2b */
trap_fd, /* 0x2c */
trap_fd, /* 0x2d */
trap_fd, /* 0x2e */
trap_fd, /* 0x2f */
trap_fd, /* 0x30 */
trap_fd, /* 0x31 */
trap_fd, /* 0x32 */
trap_fd, /* 0x33 */
op_incyd, /* 0x34 */
op_decyd, /* 0x35 */
op_ldydn, /* 0x36 */
trap_fd, /* 0x37 */
trap_fd, /* 0x38 */
op_addys, /* 0x39 */
trap_fd, /* 0x3a */
trap_fd, /* 0x3b */
trap_fd, /* 0x3c */
trap_fd, /* 0x3d */
trap_fd, /* 0x3e */
trap_fd, /* 0x3f */
trap_fd, /* 0x40 */
trap_fd, /* 0x41 */
trap_fd, /* 0x42 */
trap_fd, /* 0x43 */
trap_fd, /* 0x44 */
trap_fd, /* 0x45 */
op_ldbyd, /* 0x46 */
trap_fd, /* 0x47 */
trap_fd, /* 0x48 */
trap_fd, /* 0x49 */
trap_fd, /* 0x4a */
trap_fd, /* 0x4b */
trap_fd, /* 0x4c */
trap_fd, /* 0x4d */
op_ldcyd, /* 0x4e */
trap_fd, /* 0x4f */
trap_fd, /* 0x50 */
trap_fd, /* 0x51 */
trap_fd, /* 0x52 */
trap_fd, /* 0x53 */
trap_fd, /* 0x54 */
trap_fd, /* 0x55 */
op_lddyd, /* 0x56 */
trap_fd, /* 0x57 */
trap_fd, /* 0x58 */
trap_fd, /* 0x59 */
trap_fd, /* 0x5a */
trap_fd, /* 0x5b */
trap_fd, /* 0x5c */
trap_fd, /* 0x5d */
op_ldeyd, /* 0x5e */
trap_fd, /* 0x5f */
trap_fd, /* 0x60 */
trap_fd, /* 0x61 */
trap_fd, /* 0x62 */
trap_fd, /* 0x63 */
trap_fd, /* 0x64 */
trap_fd, /* 0x65 */
op_ldhyd, /* 0x66 */
trap_fd, /* 0x67 */
trap_fd, /* 0x68 */
trap_fd, /* 0x69 */
trap_fd, /* 0x6a */
trap_fd, /* 0x6b */
trap_fd, /* 0x6c */
trap_fd, /* 0x6d */
op_ldlyd, /* 0x6e */
trap_fd, /* 0x6f */
op_ldydb, /* 0x70 */
op_ldydc, /* 0x71 */
op_ldydd, /* 0x72 */
op_ldyde, /* 0x73 */
op_ldydh, /* 0x74 */
op_ldydl, /* 0x75 */
trap_fd, /* 0x76 */
op_ldyda, /* 0x77 */
trap_fd, /* 0x78 */
trap_fd, /* 0x79 */
trap_fd, /* 0x7a */
trap_fd, /* 0x7b */
trap_fd, /* 0x7c */
trap_fd, /* 0x7d */
op_ldayd, /* 0x7e */
trap_fd, /* 0x7f */
trap_fd, /* 0x80 */
trap_fd, /* 0x81 */
trap_fd, /* 0x82 */
trap_fd, /* 0x83 */
trap_fd, /* 0x84 */
trap_fd, /* 0x85 */
op_adayd, /* 0x86 */
trap_fd, /* 0x87 */
trap_fd, /* 0x88 */
trap_fd, /* 0x89 */
trap_fd, /* 0x8a */
trap_fd, /* 0x8b */
trap_fd, /* 0x8c */
trap_fd, /* 0x8d */
op_acayd, /* 0x8e */
trap_fd, /* 0x8f */
trap_fd, /* 0x90 */
trap_fd, /* 0x91 */
trap_fd, /* 0x92 */
trap_fd, /* 0x93 */
trap_fd, /* 0x94 */
trap_fd, /* 0x95 */
op_suayd, /* 0x96 */
trap_fd, /* 0x97 */
trap_fd, /* 0x98 */
trap_fd, /* 0x99 */
trap_fd, /* 0x9a */
trap_fd, /* 0x9b */
trap_fd, /* 0x9c */
trap_fd, /* 0x9d */
op_scayd, /* 0x9e */
trap_fd, /* 0x9f */
trap_fd, /* 0xa0 */
trap_fd, /* 0xa1 */
trap_fd, /* 0xa2 */
trap_fd, /* 0xa3 */
trap_fd, /* 0xa4 */
trap_fd, /* 0xa5 */
op_andyd, /* 0xa6 */
trap_fd, /* 0xa7 */
trap_fd, /* 0xa8 */
trap_fd, /* 0xa9 */
trap_fd, /* 0xaa */
trap_fd, /* 0xab */
trap_fd, /* 0xac */
trap_fd, /* 0xad */
op_xoryd, /* 0xae */
trap_fd, /* 0xaf */
trap_fd, /* 0xb0 */
trap_fd, /* 0xb1 */
trap_fd, /* 0xb2 */
trap_fd, /* 0xb3 */
trap_fd, /* 0xb4 */
trap_fd, /* 0xb5 */
op_oryd, /* 0xb6 */
trap_fd, /* 0xb7 */
trap_fd, /* 0xb8 */
trap_fd, /* 0xb9 */
trap_fd, /* 0xba */
trap_fd, /* 0xbb */
trap_fd, /* 0xbc */
trap_fd, /* 0xbd */
op_cpyd, /* 0xbe */
trap_fd, /* 0xbf */
trap_fd, /* 0xc0 */
trap_fd, /* 0xc1 */
trap_fd, /* 0xc2 */
trap_fd, /* 0xc3 */
trap_fd, /* 0xc4 */
trap_fd, /* 0xc5 */
trap_fd, /* 0xc6 */
trap_fd, /* 0xc7 */
trap_fd, /* 0xc8 */
trap_fd, /* 0xc9 */
trap_fd, /* 0xca */
op_fdcb_handel, /* 0xcb */
trap_fd, /* 0xcc */
trap_fd, /* 0xcd */
trap_fd, /* 0xce */
trap_fd, /* 0xcf */
trap_fd, /* 0xd0 */
trap_fd, /* 0xd1 */
trap_fd, /* 0xd2 */
trap_fd, /* 0xd3 */
trap_fd, /* 0xd4 */
trap_fd, /* 0xd5 */
trap_fd, /* 0xd6 */
trap_fd, /* 0xd7 */
trap_fd, /* 0xd8 */
trap_fd, /* 0xd9 */
trap_fd, /* 0xda */
trap_fd, /* 0xdb */
trap_fd, /* 0xdc */
trap_fd, /* 0xdd */
trap_fd, /* 0xde */
trap_fd, /* 0xdf */
trap_fd, /* 0xe0 */
op_popiy, /* 0xe1 */
trap_fd, /* 0xe2 */
op_exspy, /* 0xe3 */
trap_fd, /* 0xe4 */
op_pusiy, /* 0xe5 */
trap_fd, /* 0xe6 */
trap_fd, /* 0xe7 */
trap_fd, /* 0xe8 */
op_jpiy, /* 0xe9 */
trap_fd, /* 0xea */
trap_fd, /* 0xeb */
trap_fd, /* 0xec */
trap_fd, /* 0xed */
trap_fd, /* 0xee */
trap_fd, /* 0xef */
trap_fd, /* 0xf0 */
trap_fd, /* 0xf1 */
trap_fd, /* 0xf2 */
trap_fd, /* 0xf3 */
trap_fd, /* 0xf4 */
trap_fd, /* 0xf5 */
trap_fd, /* 0xf6 */
trap_fd, /* 0xf7 */
trap_fd, /* 0xf8 */
op_ldspy, /* 0xf9 */
trap_fd, /* 0xfa */
trap_fd, /* 0xfb */
trap_fd, /* 0xfc */
trap_fd, /* 0xfd */
trap_fd, /* 0xfe */
trap_fd /* 0xff */
};
#ifdef WANT_TIM
t = (*op_fd[*PC++]) (); /* execute next opcode */
#else
(*op_fd[*PC++]) ();
#endif
#ifdef WANT_PCC
if (PC > ram + 65535) /* correct PC overrun */
PC = ram;
#endif
return(t);
}
/*
* This function traps all illegal opcodes following the
* initial 0xfd of a multi byte opcode.
*/
static int trap_fd(void)
{
cpu_error = OPTRAP2;
cpu_state = STOPPED;
return(0);
}
static int op_popiy(void) /* POP IY */
{
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
IY = *STACK++;
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
IY += *STACK++ << 8;
return(14);
}
static int op_pusiy(void) /* PUSH IY */
{
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
*--STACK = IY >> 8;
#ifdef WANT_SPC
if (STACK <= ram)
STACK = ram + 65536L;
#endif
*--STACK = IY;
return(15);
}
static int op_jpiy(void) /* JP (IY) */
{
PC = ram + IY;
return(8);
}
static int op_exspy(void) /* EX (SP),IY */
{
register int i;
i = *STACK + (*(STACK + 1) << 8);
*STACK = IY;
*(STACK + 1) = IY >> 8;
IY = i;
return(23);
}
static int op_ldspy(void) /* LD SP,IY */
{
STACK = ram + IY;
return(10);
}
static int op_ldiynn(void) /* LD IY,nn */
{
IY = *PC++;
IY += *PC++ << 8;
return(14);
}
static int op_ldiyinn(void) /* LD IY,(nn) */
{
register BYTE *p;
p = ram + *PC++;
p += *PC++ << 8;
IY = *p++;
IY += *p << 8;
return(20);
}
static int op_ldiny(void) /* LD (nn),IY */
{
register BYTE *p;
p = ram + *PC++;
p += *PC++ << 8;
*p++ = IY;
*p = IY >> 8;
return(20);
}
static int op_adayd(void) /* ADD A,(IY+d) */
{
register int i;
register BYTE P;
P = *(ram + IY + (char) *PC++);
((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A + (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(19);
}
static int op_acayd(void) /* ADC A,(IY+d) */
{
register int i, carry;
register BYTE P;
carry = (F & C_FLAG) ? 1 : 0;
P = *(ram + IY + (char) *PC++);
((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A + (char) P + carry;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(19);
}
static int op_suayd(void) /* SUB A,(IY+d) */
{
register int i;
register BYTE P;
P = *(ram + IY + (char) *PC++);
((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A - (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_scayd(void) /* SBC A,(IY+d) */
{
register int i, carry;
register BYTE P;
carry = (F & C_FLAG) ? 1 : 0;
P = *(ram + IY + (char) *PC++);
((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
A = i = (char) A - (char) P - carry;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_andyd(void) /* AND (IY+d) */
{
A &= *(ram + IY + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= H_FLAG;
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(N_FLAG | C_FLAG);
return(19);
}
static int op_xoryd(void) /* XOR (IY+d) */
{
A ^= *(ram + IY + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(H_FLAG | N_FLAG | C_FLAG);
return(19);
}
static int op_oryd(void) /* OR (IY+d) */
{
A |= *(ram + IY + (char) *PC++);
(A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
F &= ~(H_FLAG | N_FLAG | C_FLAG);
return(19);
}
static int op_cpyd(void) /* CP (IY+d) */
{
register int i;
register BYTE P;
P = *(ram + IY + (char) *PC++);
((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG);
i = (char) A - (char) P;
(i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(19);
}
static int op_incyd(void) /* INC (IY+d) */
{
register BYTE *p;
p = ram + IY + (char) *PC++;
((*p & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(*p)++;
(*p == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F &= ~N_FLAG;
return(23);
}
static int op_decyd(void) /* DEC (IY+d) */
{
register BYTE *p;
p = ram + IY + (char) *PC++;
(((*p - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(*p)--;
(*p == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
F |= N_FLAG;
return(23);
}
static int op_addyb(void) /* ADD IY,BC */
{
register int carry;
BYTE iyl = IY & 0xff;
BYTE iyh = IY >> 8;
carry = (iyl + C > 255) ? 1 : 0;
iyl += C;
((iyh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(iyh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
iyh += B + carry;
IY = (iyh << 8) + iyl;
F &= ~N_FLAG;
return(15);
}
static int op_addyd(void) /* ADD IY,DE */
{
register int carry;
BYTE iyl = IY & 0xff;
BYTE iyh = IY >> 8;
carry = (iyl + E > 255) ? 1 : 0;
iyl += E;
((iyh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(iyh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
iyh += D + carry;
IY = (iyh << 8) + iyl;
F &= ~N_FLAG;
return(15);
}
static int op_addys(void) /* ADD IY,SP */
{
register int carry;
BYTE iyl = IY & 0xff;
BYTE iyh = IY >> 8;
BYTE spl = (STACK - ram) & 0xff;
BYTE sph = (STACK - ram) >> 8;
carry = (iyl + spl > 255) ? 1 : 0;
iyl += spl;
((iyh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(iyh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
iyh += sph + carry;
IY = (iyh << 8) + iyl;
F &= ~N_FLAG;
return(15);
}
static int op_addyy(void) /* ADD IY,IY */
{
register int carry;
BYTE iyl = IY & 0xff;
BYTE iyh = IY >> 8;
carry = (iyl << 1 > 255) ? 1 : 0;
iyl <<= 1;
((iyh & 0xf) + (iyh & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG);
(iyh + iyh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG);
iyh += iyh + carry;
IY = (iyh << 8) + iyl;
F &= ~N_FLAG;
return(15);
}
static int op_inciy(void) /* INC IY */
{
IY++;
return(10);
}
static int op_deciy(void) /* DEC IY */
{
IY--;
return(10);
}
static int op_ldayd(void) /* LD A,(IY+d) */
{
A = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldbyd(void) /* LD B,(IY+d) */
{
B = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldcyd(void) /* LD C,(IY+d) */
{
C = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_lddyd(void) /* LD D,(IY+d) */
{
D = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldeyd(void) /* LD E,(IY+d) */
{
E = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldhyd(void) /* LD H,(IY+d) */
{
H = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldlyd(void) /* LD L,(IY+d) */
{
L = *(IY + (char) *PC++ + ram);
return(19);
}
static int op_ldyda(void) /* LD (IY+d),A */
{
*(IY + (char) *PC++ + ram) = A;
return(19);
}
static int op_ldydb(void) /* LD (IY+d),B */
{
*(IY + (char) *PC++ + ram) = B;
return(19);
}
static int op_ldydc(void) /* LD (IY+d),C */
{
*(IY + (char) *PC++ + ram) = C;
return(19);
}
static int op_ldydd(void) /* LD (IY+d),D */
{
*(IY + (char) *PC++ + ram) = D;
return(19);
}
static int op_ldyde(void) /* LD (IY+d),E */
{
*(IY + (char) *PC++ + ram) = E;
return(19);
}
static int op_ldydh(void) /* LD (IY+d),H */
{
*(IY + (char) *PC++ + ram) = H;
return(19);
}
static int op_ldydl(void) /* LD (IY+d),L */
{
*(IY + (char) *PC++ + ram) = L;
return(19);
}
static int op_ldydn(void) /* LD (IY+d),n */
{
register int d;
d = (char) *PC++;
*(IY + d + ram) = *PC++;
return(19);
}

Binary file not shown.

View File

@@ -0,0 +1,617 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* Like the function "cpu()" this one emulates 4 byte opcodes
* starting with 0xdd 0xcb
*/
#include "sim.h"
#include "simglb.h"
static int trap_ddcb(void);
static int op_tb0ixd(int), op_tb1ixd(int), op_tb2ixd(int), op_tb3ixd(int);
static int op_tb4ixd(int), op_tb5ixd(int), op_tb6ixd(int), op_tb7ixd(int);
static int op_rb0ixd(int), op_rb1ixd(int), op_rb2ixd(int), op_rb3ixd(int);
static int op_rb4ixd(int), op_rb5ixd(int), op_rb6ixd(int), op_rb7ixd(int);
static int op_sb0ixd(int), op_sb1ixd(int), op_sb2ixd(int), op_sb3ixd(int);
static int op_sb4ixd(int), op_sb5ixd(int), op_sb6ixd(int), op_sb7ixd(int);
static int op_rlcixd(int), op_rrcixd(int), op_rlixd(int), op_rrixd(int);
static int op_slaixd(int), op_sraixd(int), op_srlixd(int);
int op_ddcb_handel(void)
{
static int (*op_ddcb[256]) () = {
trap_ddcb, /* 0x00 */
trap_ddcb, /* 0x01 */
trap_ddcb, /* 0x02 */
trap_ddcb, /* 0x03 */
trap_ddcb, /* 0x04 */
trap_ddcb, /* 0x05 */
op_rlcixd, /* 0x06 */
trap_ddcb, /* 0x07 */
trap_ddcb, /* 0x08 */
trap_ddcb, /* 0x09 */
trap_ddcb, /* 0x0a */
trap_ddcb, /* 0x0b */
trap_ddcb, /* 0x0c */
trap_ddcb, /* 0x0d */
op_rrcixd, /* 0x0e */
trap_ddcb, /* 0x0f */
trap_ddcb, /* 0x10 */
trap_ddcb, /* 0x11 */
trap_ddcb, /* 0x12 */
trap_ddcb, /* 0x13 */
trap_ddcb, /* 0x14 */
trap_ddcb, /* 0x15 */
op_rlixd, /* 0x16 */
trap_ddcb, /* 0x17 */
trap_ddcb, /* 0x18 */
trap_ddcb, /* 0x19 */
trap_ddcb, /* 0x1a */
trap_ddcb, /* 0x1b */
trap_ddcb, /* 0x1c */
trap_ddcb, /* 0x1d */
op_rrixd, /* 0x1e */
trap_ddcb, /* 0x1f */
trap_ddcb, /* 0x20 */
trap_ddcb, /* 0x21 */
trap_ddcb, /* 0x22 */
trap_ddcb, /* 0x23 */
trap_ddcb, /* 0x24 */
trap_ddcb, /* 0x25 */
op_slaixd, /* 0x26 */
trap_ddcb, /* 0x27 */
trap_ddcb, /* 0x28 */
trap_ddcb, /* 0x29 */
trap_ddcb, /* 0x2a */
trap_ddcb, /* 0x2b */
trap_ddcb, /* 0x2c */
trap_ddcb, /* 0x2d */
op_sraixd, /* 0x2e */
trap_ddcb, /* 0x2f */
trap_ddcb, /* 0x30 */
trap_ddcb, /* 0x31 */
trap_ddcb, /* 0x32 */
trap_ddcb, /* 0x33 */
trap_ddcb, /* 0x34 */
trap_ddcb, /* 0x35 */
trap_ddcb, /* 0x36 */
trap_ddcb, /* 0x37 */
trap_ddcb, /* 0x38 */
trap_ddcb, /* 0x39 */
trap_ddcb, /* 0x3a */
trap_ddcb, /* 0x3b */
trap_ddcb, /* 0x3c */
trap_ddcb, /* 0x3d */
op_srlixd, /* 0x3e */
trap_ddcb, /* 0x3f */
trap_ddcb, /* 0x40 */
trap_ddcb, /* 0x41 */
trap_ddcb, /* 0x42 */
trap_ddcb, /* 0x43 */
trap_ddcb, /* 0x44 */
trap_ddcb, /* 0x45 */
op_tb0ixd, /* 0x46 */
trap_ddcb, /* 0x47 */
trap_ddcb, /* 0x48 */
trap_ddcb, /* 0x49 */
trap_ddcb, /* 0x4a */
trap_ddcb, /* 0x4b */
trap_ddcb, /* 0x4c */
trap_ddcb, /* 0x4d */
op_tb1ixd, /* 0x4e */
trap_ddcb, /* 0x4f */
trap_ddcb, /* 0x50 */
trap_ddcb, /* 0x51 */
trap_ddcb, /* 0x52 */
trap_ddcb, /* 0x53 */
trap_ddcb, /* 0x54 */
trap_ddcb, /* 0x55 */
op_tb2ixd, /* 0x56 */
trap_ddcb, /* 0x57 */
trap_ddcb, /* 0x58 */
trap_ddcb, /* 0x59 */
trap_ddcb, /* 0x5a */
trap_ddcb, /* 0x5b */
trap_ddcb, /* 0x5c */
trap_ddcb, /* 0x5d */
op_tb3ixd, /* 0x5e */
trap_ddcb, /* 0x5f */
trap_ddcb, /* 0x60 */
trap_ddcb, /* 0x61 */
trap_ddcb, /* 0x62 */
trap_ddcb, /* 0x63 */
trap_ddcb, /* 0x64 */
trap_ddcb, /* 0x65 */
op_tb4ixd, /* 0x66 */
trap_ddcb, /* 0x67 */
trap_ddcb, /* 0x68 */
trap_ddcb, /* 0x69 */
trap_ddcb, /* 0x6a */
trap_ddcb, /* 0x6b */
trap_ddcb, /* 0x6c */
trap_ddcb, /* 0x6d */
op_tb5ixd, /* 0x6e */
trap_ddcb, /* 0x6f */
trap_ddcb, /* 0x70 */
trap_ddcb, /* 0x71 */
trap_ddcb, /* 0x72 */
trap_ddcb, /* 0x73 */
trap_ddcb, /* 0x74 */
trap_ddcb, /* 0x75 */
op_tb6ixd, /* 0x76 */
trap_ddcb, /* 0x77 */
trap_ddcb, /* 0x78 */
trap_ddcb, /* 0x79 */
trap_ddcb, /* 0x7a */
trap_ddcb, /* 0x7b */
trap_ddcb, /* 0x7c */
trap_ddcb, /* 0x7d */
op_tb7ixd, /* 0x7e */
trap_ddcb, /* 0x7f */
trap_ddcb, /* 0x80 */
trap_ddcb, /* 0x81 */
trap_ddcb, /* 0x82 */
trap_ddcb, /* 0x83 */
trap_ddcb, /* 0x84 */
trap_ddcb, /* 0x85 */
op_rb0ixd, /* 0x86 */
trap_ddcb, /* 0x87 */
trap_ddcb, /* 0x88 */
trap_ddcb, /* 0x89 */
trap_ddcb, /* 0x8a */
trap_ddcb, /* 0x8b */
trap_ddcb, /* 0x8c */
trap_ddcb, /* 0x8d */
op_rb1ixd, /* 0x8e */
trap_ddcb, /* 0x8f */
trap_ddcb, /* 0x90 */
trap_ddcb, /* 0x91 */
trap_ddcb, /* 0x92 */
trap_ddcb, /* 0x93 */
trap_ddcb, /* 0x94 */
trap_ddcb, /* 0x95 */
op_rb2ixd, /* 0x96 */
trap_ddcb, /* 0x97 */
trap_ddcb, /* 0x98 */
trap_ddcb, /* 0x99 */
trap_ddcb, /* 0x9a */
trap_ddcb, /* 0x9b */
trap_ddcb, /* 0x9c */
trap_ddcb, /* 0x9d */
op_rb3ixd, /* 0x9e */
trap_ddcb, /* 0x9f */
trap_ddcb, /* 0xa0 */
trap_ddcb, /* 0xa1 */
trap_ddcb, /* 0xa2 */
trap_ddcb, /* 0xa3 */
trap_ddcb, /* 0xa4 */
trap_ddcb, /* 0xa5 */
op_rb4ixd, /* 0xa6 */
trap_ddcb, /* 0xa7 */
trap_ddcb, /* 0xa8 */
trap_ddcb, /* 0xa9 */
trap_ddcb, /* 0xaa */
trap_ddcb, /* 0xab */
trap_ddcb, /* 0xac */
trap_ddcb, /* 0xad */
op_rb5ixd, /* 0xae */
trap_ddcb, /* 0xaf */
trap_ddcb, /* 0xb0 */
trap_ddcb, /* 0xb1 */
trap_ddcb, /* 0xb2 */
trap_ddcb, /* 0xb3 */
trap_ddcb, /* 0xb4 */
trap_ddcb, /* 0xb5 */
op_rb6ixd, /* 0xb6 */
trap_ddcb, /* 0xb7 */
trap_ddcb, /* 0xb8 */
trap_ddcb, /* 0xb9 */
trap_ddcb, /* 0xba */
trap_ddcb, /* 0xbb */
trap_ddcb, /* 0xbc */
trap_ddcb, /* 0xbd */
op_rb7ixd, /* 0xbe */
trap_ddcb, /* 0xbf */
trap_ddcb, /* 0xc0 */
trap_ddcb, /* 0xc1 */
trap_ddcb, /* 0xc2 */
trap_ddcb, /* 0xc3 */
trap_ddcb, /* 0xc4 */
trap_ddcb, /* 0xc5 */
op_sb0ixd, /* 0xc6 */
trap_ddcb, /* 0xc7 */
trap_ddcb, /* 0xc8 */
trap_ddcb, /* 0xc9 */
trap_ddcb, /* 0xca */
trap_ddcb, /* 0xcb */
trap_ddcb, /* 0xcc */
trap_ddcb, /* 0xcd */
op_sb1ixd, /* 0xce */
trap_ddcb, /* 0xcf */
trap_ddcb, /* 0xd0 */
trap_ddcb, /* 0xd1 */
trap_ddcb, /* 0xd2 */
trap_ddcb, /* 0xd3 */
trap_ddcb, /* 0xd4 */
trap_ddcb, /* 0xd5 */
op_sb2ixd, /* 0xd6 */
trap_ddcb, /* 0xd7 */
trap_ddcb, /* 0xd8 */
trap_ddcb, /* 0xd9 */
trap_ddcb, /* 0xda */
trap_ddcb, /* 0xdb */
trap_ddcb, /* 0xdc */
trap_ddcb, /* 0xdd */
op_sb3ixd, /* 0xde */
trap_ddcb, /* 0xdf */
trap_ddcb, /* 0xe0 */
trap_ddcb, /* 0xe1 */
trap_ddcb, /* 0xe2 */
trap_ddcb, /* 0xe3 */
trap_ddcb, /* 0xe4 */
trap_ddcb, /* 0xe5 */
op_sb4ixd, /* 0xe6 */
trap_ddcb, /* 0xe7 */
trap_ddcb, /* 0xe8 */
trap_ddcb, /* 0xe9 */
trap_ddcb, /* 0xea */
trap_ddcb, /* 0xeb */
trap_ddcb, /* 0xec */
trap_ddcb, /* 0xed */
op_sb5ixd, /* 0xee */
trap_ddcb, /* 0xef */
trap_ddcb, /* 0xf0 */
trap_ddcb, /* 0xf1 */
trap_ddcb, /* 0xf2 */
trap_ddcb, /* 0xf3 */
trap_ddcb, /* 0xf4 */
trap_ddcb, /* 0xf5 */
op_sb6ixd, /* 0xf6 */
trap_ddcb, /* 0xf7 */
trap_ddcb, /* 0xf8 */
trap_ddcb, /* 0xf9 */
trap_ddcb, /* 0xfa */
trap_ddcb, /* 0xfb */
trap_ddcb, /* 0xfc */
trap_ddcb, /* 0xfd */
op_sb7ixd, /* 0xfe */
trap_ddcb /* 0xff */
};
register int d;
register int t;
d = (char) *PC++;
#ifdef WANT_PCC
if (PC > ram + 65535) /* correct PC overrun */
PC = ram;
#endif
#ifdef WANT_TIM
t = (*op_ddcb[*PC++]) (d); /* execute next opcode */
#else
(*op_ddcb[*PC++]) (d);
#endif
#ifdef WANT_PCC
if (PC > ram + 65535) /* again correct PC overrun */
PC = ram;
#endif
return(t);
}
/*
* This function traps all illegal opcodes following the
* initial 0xdd 0xcb of a 4 byte opcode.
*/
static int trap_ddcb(void)
{
cpu_error = OPTRAP4;
cpu_state = STOPPED;
return(0);
}
static int op_tb0ixd(int data) /* BIT 0,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb1ixd(int data) /* BIT 1,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb2ixd(int data) /* BIT 2,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb3ixd(int data) /* BIT 3,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb4ixd(int data) /* BIT 4,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb5ixd(int data) /* BIT 5,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb6ixd(int data) /* BIT 6,(IX+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IX + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb7ixd(int data) /* BIT 7,(IX+d) */
{
F &= ~N_FLAG;
F |= H_FLAG;
if (*(ram + IX + data) & 128) {
F &= ~(Z_FLAG | P_FLAG);
F |= S_FLAG;
} else {
F |= (Z_FLAG | P_FLAG);
F &= ~S_FLAG;
}
return(20);
}
static int op_rb0ixd(int data) /* RES 0,(IX+d) */
{
*(ram + IX + data) &= ~1;
return(23);
}
static int op_rb1ixd(int data) /* RES 1,(IX+d) */
{
*(ram + IX + data) &= ~2;
return(23);
}
static int op_rb2ixd(int data) /* RES 2,(IX+d) */
{
*(ram + IX + data) &= ~4;
return(23);
}
static int op_rb3ixd(int data) /* RES 3,(IX+d) */
{
*(ram + IX + data) &= ~8;
return(23);
}
static int op_rb4ixd(int data) /* RES 4,(IX+d) */
{
*(ram + IX + data) &= ~16;
return(23);
}
static int op_rb5ixd(int data) /* RES 5,(IX+d) */
{
*(ram + IX + data) &= ~32;
return(23);
}
static int op_rb6ixd(int data) /* RES 6,(IX+d) */
{
*(ram + IX + data) &= ~64;
return(23);
}
static int op_rb7ixd(int data) /* RES 7,(IX+d) */
{
*(ram + IX + data) &= ~128;
return(23);
}
static int op_sb0ixd(int data) /* SET 0,(IX+d) */
{
*(ram + IX + data) |= 1;
return(23);
}
static int op_sb1ixd(int data) /* SET 1,(IX+d) */
{
*(ram + IX + data) |= 2;
return(23);
}
static int op_sb2ixd(int data) /* SET 2,(IX+d) */
{
*(ram + IX + data) |= 4;
return(23);
}
static int op_sb3ixd(int data) /* SET 3,(IX+d) */
{
*(ram + IX + data) |= 8;
return(23);
}
static int op_sb4ixd(int data) /* SET 4,(IX+d) */
{
*(ram + IX + data) |= 16;
return(23);
}
static int op_sb5ixd(int data) /* SET 5,(IX+d) */
{
*(ram + IX + data) |= 32;
return(23);
}
static int op_sb6ixd(int data) /* SET 6,(IX+d) */
{
*(ram + IX + data) |= 64;
return(23);
}
static int op_sb7ixd(int data) /* SET 7,(IX+d) */
{
*(ram + IX + data) |= 128;
return(23);
}
static int op_rlcixd(int data) /* RLC (IX+d) */
{
register int i;
register BYTE *p;
p = ram + IX + data;
i = *p & 128;
(i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
F &= ~(H_FLAG | N_FLAG);
*p <<= 1;
if (i) *p |= 1;
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rrcixd(int data) /* RRC (IX+d) */
{
register int i;
register BYTE *p;
p = ram + IX + data;
i = *p & 1;
(i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
F &= ~(H_FLAG | N_FLAG);
*p >>= 1;
if (i) *p |= 128;
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rlixd(int data) /* RL (IX+d) */
{
register int old_c_flag;
register BYTE *p;
p = ram + IX + data;
old_c_flag = F & C_FLAG;
(*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p <<= 1;
if (old_c_flag) *p |= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rrixd(int data) /* RR (IX+d) */
{
register int old_c_flag;
register BYTE *p;
old_c_flag = F & C_FLAG;
p = ram + IX + data;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
if (old_c_flag) *p |= 128;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_slaixd(int data) /* SLA (IX+d) */
{
register BYTE *p;
p = ram + IX + data;
(*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p <<= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_sraixd(int data) /* SRA (IX+d) */
{
register int i;
register BYTE *p;
p = ram + IX + data;
i = *p & 128;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
*p |= i;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_srlixd(int data) /* SRL (IX+d) */
{
register BYTE *p;
p = ram + IX + data;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}

Binary file not shown.

View File

@@ -0,0 +1,617 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V(3.1)
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* Like the function "cpu()" this one emulates 4 byte opcodes
* starting with 0xfd 0xcb
*/
#include "sim.h"
#include "simglb.h"
static int trap_fdcb(void);
static int op_tb0iyd(int), op_tb1iyd(int), op_tb2iyd(int), op_tb3iyd(int);
static int op_tb4iyd(int), op_tb5iyd(int), op_tb6iyd(int), op_tb7iyd(int);
static int op_rb0iyd(int), op_rb1iyd(int), op_rb2iyd(int), op_rb3iyd(int);
static int op_rb4iyd(int), op_rb5iyd(int), op_rb6iyd(int), op_rb7iyd(int);
static int op_sb0iyd(int), op_sb1iyd(int), op_sb2iyd(int), op_sb3iyd(int);
static int op_sb4iyd(int), op_sb5iyd(int), op_sb6iyd(int), op_sb7iyd(int);
static int op_rlciyd(int), op_rrciyd(int), op_rliyd(int), op_rriyd(int);
static int op_slaiyd(int), op_sraiyd(int), op_srliyd(int);
int op_fdcb_handel(void)
{
static int (*op_fdcb[256]) () = {
trap_fdcb, /* 0x00 */
trap_fdcb, /* 0x01 */
trap_fdcb, /* 0x02 */
trap_fdcb, /* 0x03 */
trap_fdcb, /* 0x04 */
trap_fdcb, /* 0x05 */
op_rlciyd, /* 0x06 */
trap_fdcb, /* 0x07 */
trap_fdcb, /* 0x08 */
trap_fdcb, /* 0x09 */
trap_fdcb, /* 0x0a */
trap_fdcb, /* 0x0b */
trap_fdcb, /* 0x0c */
trap_fdcb, /* 0x0d */
op_rrciyd, /* 0x0e */
trap_fdcb, /* 0x0f */
trap_fdcb, /* 0x10 */
trap_fdcb, /* 0x11 */
trap_fdcb, /* 0x12 */
trap_fdcb, /* 0x13 */
trap_fdcb, /* 0x14 */
trap_fdcb, /* 0x15 */
op_rliyd, /* 0x16 */
trap_fdcb, /* 0x17 */
trap_fdcb, /* 0x18 */
trap_fdcb, /* 0x19 */
trap_fdcb, /* 0x1a */
trap_fdcb, /* 0x1b */
trap_fdcb, /* 0x1c */
trap_fdcb, /* 0x1d */
op_rriyd, /* 0x1e */
trap_fdcb, /* 0x1f */
trap_fdcb, /* 0x20 */
trap_fdcb, /* 0x21 */
trap_fdcb, /* 0x22 */
trap_fdcb, /* 0x23 */
trap_fdcb, /* 0x24 */
trap_fdcb, /* 0x25 */
op_slaiyd, /* 0x26 */
trap_fdcb, /* 0x27 */
trap_fdcb, /* 0x28 */
trap_fdcb, /* 0x29 */
trap_fdcb, /* 0x2a */
trap_fdcb, /* 0x2b */
trap_fdcb, /* 0x2c */
trap_fdcb, /* 0x2d */
op_sraiyd, /* 0x2e */
trap_fdcb, /* 0x2f */
trap_fdcb, /* 0x30 */
trap_fdcb, /* 0x31 */
trap_fdcb, /* 0x32 */
trap_fdcb, /* 0x33 */
trap_fdcb, /* 0x34 */
trap_fdcb, /* 0x35 */
trap_fdcb, /* 0x36 */
trap_fdcb, /* 0x37 */
trap_fdcb, /* 0x38 */
trap_fdcb, /* 0x39 */
trap_fdcb, /* 0x3a */
trap_fdcb, /* 0x3b */
trap_fdcb, /* 0x3c */
trap_fdcb, /* 0x3d */
op_srliyd, /* 0x3e */
trap_fdcb, /* 0x3f */
trap_fdcb, /* 0x40 */
trap_fdcb, /* 0x41 */
trap_fdcb, /* 0x42 */
trap_fdcb, /* 0x43 */
trap_fdcb, /* 0x44 */
trap_fdcb, /* 0x45 */
op_tb0iyd, /* 0x46 */
trap_fdcb, /* 0x47 */
trap_fdcb, /* 0x48 */
trap_fdcb, /* 0x49 */
trap_fdcb, /* 0x4a */
trap_fdcb, /* 0x4b */
trap_fdcb, /* 0x4c */
trap_fdcb, /* 0x4d */
op_tb1iyd, /* 0x4e */
trap_fdcb, /* 0x4f */
trap_fdcb, /* 0x50 */
trap_fdcb, /* 0x51 */
trap_fdcb, /* 0x52 */
trap_fdcb, /* 0x53 */
trap_fdcb, /* 0x54 */
trap_fdcb, /* 0x55 */
op_tb2iyd, /* 0x56 */
trap_fdcb, /* 0x57 */
trap_fdcb, /* 0x58 */
trap_fdcb, /* 0x59 */
trap_fdcb, /* 0x5a */
trap_fdcb, /* 0x5b */
trap_fdcb, /* 0x5c */
trap_fdcb, /* 0x5d */
op_tb3iyd, /* 0x5e */
trap_fdcb, /* 0x5f */
trap_fdcb, /* 0x60 */
trap_fdcb, /* 0x61 */
trap_fdcb, /* 0x62 */
trap_fdcb, /* 0x63 */
trap_fdcb, /* 0x64 */
trap_fdcb, /* 0x65 */
op_tb4iyd, /* 0x66 */
trap_fdcb, /* 0x67 */
trap_fdcb, /* 0x68 */
trap_fdcb, /* 0x69 */
trap_fdcb, /* 0x6a */
trap_fdcb, /* 0x6b */
trap_fdcb, /* 0x6c */
trap_fdcb, /* 0x6d */
op_tb5iyd, /* 0x6e */
trap_fdcb, /* 0x6f */
trap_fdcb, /* 0x70 */
trap_fdcb, /* 0x71 */
trap_fdcb, /* 0x72 */
trap_fdcb, /* 0x73 */
trap_fdcb, /* 0x74 */
trap_fdcb, /* 0x75 */
op_tb6iyd, /* 0x76 */
trap_fdcb, /* 0x77 */
trap_fdcb, /* 0x78 */
trap_fdcb, /* 0x79 */
trap_fdcb, /* 0x7a */
trap_fdcb, /* 0x7b */
trap_fdcb, /* 0x7c */
trap_fdcb, /* 0x7d */
op_tb7iyd, /* 0x7e */
trap_fdcb, /* 0x7f */
trap_fdcb, /* 0x80 */
trap_fdcb, /* 0x81 */
trap_fdcb, /* 0x82 */
trap_fdcb, /* 0x83 */
trap_fdcb, /* 0x84 */
trap_fdcb, /* 0x85 */
op_rb0iyd, /* 0x86 */
trap_fdcb, /* 0x87 */
trap_fdcb, /* 0x88 */
trap_fdcb, /* 0x89 */
trap_fdcb, /* 0x8a */
trap_fdcb, /* 0x8b */
trap_fdcb, /* 0x8c */
trap_fdcb, /* 0x8d */
op_rb1iyd, /* 0x8e */
trap_fdcb, /* 0x8f */
trap_fdcb, /* 0x90 */
trap_fdcb, /* 0x91 */
trap_fdcb, /* 0x92 */
trap_fdcb, /* 0x93 */
trap_fdcb, /* 0x94 */
trap_fdcb, /* 0x95 */
op_rb2iyd, /* 0x96 */
trap_fdcb, /* 0x97 */
trap_fdcb, /* 0x98 */
trap_fdcb, /* 0x99 */
trap_fdcb, /* 0x9a */
trap_fdcb, /* 0x9b */
trap_fdcb, /* 0x9c */
trap_fdcb, /* 0x9d */
op_rb3iyd, /* 0x9e */
trap_fdcb, /* 0x9f */
trap_fdcb, /* 0xa0 */
trap_fdcb, /* 0xa1 */
trap_fdcb, /* 0xa2 */
trap_fdcb, /* 0xa3 */
trap_fdcb, /* 0xa4 */
trap_fdcb, /* 0xa5 */
op_rb4iyd, /* 0xa6 */
trap_fdcb, /* 0xa7 */
trap_fdcb, /* 0xa8 */
trap_fdcb, /* 0xa9 */
trap_fdcb, /* 0xaa */
trap_fdcb, /* 0xab */
trap_fdcb, /* 0xac */
trap_fdcb, /* 0xad */
op_rb5iyd, /* 0xae */
trap_fdcb, /* 0xaf */
trap_fdcb, /* 0xb0 */
trap_fdcb, /* 0xb1 */
trap_fdcb, /* 0xb2 */
trap_fdcb, /* 0xb3 */
trap_fdcb, /* 0xb4 */
trap_fdcb, /* 0xb5 */
op_rb6iyd, /* 0xb6 */
trap_fdcb, /* 0xb7 */
trap_fdcb, /* 0xb8 */
trap_fdcb, /* 0xb9 */
trap_fdcb, /* 0xba */
trap_fdcb, /* 0xbb */
trap_fdcb, /* 0xbc */
trap_fdcb, /* 0xbd */
op_rb7iyd, /* 0xbe */
trap_fdcb, /* 0xbf */
trap_fdcb, /* 0xc0 */
trap_fdcb, /* 0xc1 */
trap_fdcb, /* 0xc2 */
trap_fdcb, /* 0xc3 */
trap_fdcb, /* 0xc4 */
trap_fdcb, /* 0xc5 */
op_sb0iyd, /* 0xc6 */
trap_fdcb, /* 0xc7 */
trap_fdcb, /* 0xc8 */
trap_fdcb, /* 0xc9 */
trap_fdcb, /* 0xca */
trap_fdcb, /* 0xcb */
trap_fdcb, /* 0xcc */
trap_fdcb, /* 0xcd */
op_sb1iyd, /* 0xce */
trap_fdcb, /* 0xcf */
trap_fdcb, /* 0xd0 */
trap_fdcb, /* 0xd1 */
trap_fdcb, /* 0xd2 */
trap_fdcb, /* 0xd3 */
trap_fdcb, /* 0xd4 */
trap_fdcb, /* 0xd5 */
op_sb2iyd, /* 0xd6 */
trap_fdcb, /* 0xd7 */
trap_fdcb, /* 0xd8 */
trap_fdcb, /* 0xd9 */
trap_fdcb, /* 0xda */
trap_fdcb, /* 0xdb */
trap_fdcb, /* 0xdc */
trap_fdcb, /* 0xdd */
op_sb3iyd, /* 0xde */
trap_fdcb, /* 0xdf */
trap_fdcb, /* 0xe0 */
trap_fdcb, /* 0xe1 */
trap_fdcb, /* 0xe2 */
trap_fdcb, /* 0xe3 */
trap_fdcb, /* 0xe4 */
trap_fdcb, /* 0xe5 */
op_sb4iyd, /* 0xe6 */
trap_fdcb, /* 0xe7 */
trap_fdcb, /* 0xe8 */
trap_fdcb, /* 0xe9 */
trap_fdcb, /* 0xea */
trap_fdcb, /* 0xeb */
trap_fdcb, /* 0xec */
trap_fdcb, /* 0xed */
op_sb5iyd, /* 0xee */
trap_fdcb, /* 0xef */
trap_fdcb, /* 0xf0 */
trap_fdcb, /* 0xf1 */
trap_fdcb, /* 0xf2 */
trap_fdcb, /* 0xf3 */
trap_fdcb, /* 0xf4 */
trap_fdcb, /* 0xf5 */
op_sb6iyd, /* 0xf6 */
trap_fdcb, /* 0xf7 */
trap_fdcb, /* 0xf8 */
trap_fdcb, /* 0xf9 */
trap_fdcb, /* 0xfa */
trap_fdcb, /* 0xfb */
trap_fdcb, /* 0xfc */
trap_fdcb, /* 0xfd */
op_sb7iyd, /* 0xfe */
trap_fdcb /* 0xff */
};
register int d;
register int t;
d = (char) *PC++;
#ifdef WANT_PCC
if (PC > ram + 65535) /* correct PC overrun */
PC = ram;
#endif
#ifdef WANT_TIM
t = (*op_fdcb[*PC++]) (d); /* execute next opcode */
#else
(*op_fdcb[*PC++]) (d);
#endif
#ifdef WANT_PCC
if (PC > ram + 65535) /* again correct PC overrun */
PC = ram;
#endif
return(t);
}
/*
* This function traps all illegal opcodes following the
* initial 0xfd 0xcb of a 4 byte opcode.
*/
static int trap_fdcb(void)
{
cpu_error = OPTRAP4;
cpu_state = STOPPED;
return(0L);
}
static int op_tb0iyd(int data) /* BIT 0,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb1iyd(int data) /* BIT 1,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb2iyd(int data) /* BIT 2,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb3iyd(int data) /* BIT 3,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb4iyd(int data) /* BIT 4,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb5iyd(int data) /* BIT 5,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb6iyd(int data) /* BIT 6,(IY+d) */
{
F &= ~(N_FLAG | S_FLAG);
F |= H_FLAG;
(*(ram + IY + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG))
: (F |= (Z_FLAG | P_FLAG));
return(20);
}
static int op_tb7iyd(int data) /* BIT 7,(IY+d) */
{
F &= ~N_FLAG;
F |= H_FLAG;
if (*(ram + IY + data) & 128) {
F &= ~(Z_FLAG | P_FLAG);
F |= S_FLAG;
} else {
F |= (Z_FLAG | P_FLAG);
F &= ~S_FLAG;
}
return(20);
}
static int op_rb0iyd(int data) /* RES 0,(IY+d) */
{
*(ram + IY + data) &= ~1;
return(23);
}
static int op_rb1iyd(int data) /* RES 1,(IY+d) */
{
*(ram + IY + data) &= ~2;
return(23);
}
static int op_rb2iyd(int data) /* RES 2,(IY+d) */
{
*(ram + IY + data) &= ~4;
return(23);
}
static int op_rb3iyd(int data) /* RES 3,(IY+d) */
{
*(ram + IY + data) &= ~8;
return(23);
}
static int op_rb4iyd(int data) /* RES 4,(IY+d) */
{
*(ram + IY + data) &= ~16;
return(23);
}
static int op_rb5iyd(int data) /* RES 5,(IY+d) */
{
*(ram + IY + data) &= ~32;
return(23);
}
static int op_rb6iyd(int data) /* RES 6,(IY+d) */
{
*(ram + IY + data) &= ~64;
return(23);
}
static int op_rb7iyd(int data) /* RES 7,(IY+d) */
{
*(ram + IY + data) &= ~128;
return(23);
}
static int op_sb0iyd(int data) /* SET 0,(IY+d) */
{
*(ram + IY + data) |= 1;
return(23);
}
static int op_sb1iyd(int data) /* SET 1,(IY+d) */
{
*(ram + IY + data) |= 2;
return(23);
}
static int op_sb2iyd(int data) /* SET 2,(IY+d) */
{
*(ram + IY + data) |= 4;
return(23);
}
static int op_sb3iyd(int data) /* SET 3,(IY+d) */
{
*(ram + IY + data) |= 8;
return(23);
}
static int op_sb4iyd(int data) /* SET 4,(IY+d) */
{
*(ram + IY + data) |= 16;
return(23);
}
static int op_sb5iyd(int data) /* SET 5,(IY+d) */
{
*(ram + IY + data) |= 32;
return(23);
}
static int op_sb6iyd(int data) /* SET 6,(IY+d) */
{
*(ram + IY + data) |= 64;
return(23);
}
static int op_sb7iyd(int data) /* SET 7,(IY+d) */
{
*(ram + IY + data) |= 128;
return(23);
}
static int op_rlciyd(int data) /* RLC (IY+d) */
{
register int i;
register BYTE *p;
p = ram + IY + data;
i = *p & 128;
(i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
F &= ~(H_FLAG | N_FLAG);
*p <<= 1;
if (i) *p |= 1;
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rrciyd(int data) /* RRC (IY+d) */
{
register int i;
register BYTE *p;
p = ram + IY + data;
i = *p & 1;
(i) ? (F |= C_FLAG) : (F &= ~C_FLAG);
F &= ~(H_FLAG | N_FLAG);
*p >>= 1;
if (i) *p |= 128;
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rliyd(int data) /* RL (IY+d) */
{
register int old_c_flag;
register BYTE *p;
p = ram + IY + data;
old_c_flag = F & C_FLAG;
(*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p <<= 1;
if (old_c_flag) *p |= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_rriyd(int data) /* RR (IY+d) */
{
register int old_c_flag;
register BYTE *p;
old_c_flag = F & C_FLAG;
p = ram + IY + data;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
if (old_c_flag) *p |= 128;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_slaiyd(int data) /* SLA (IY+d) */
{
register BYTE *p;
p = ram + IY + data;
(*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p <<= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_sraiyd(int data) /* SRA (IY+d) */
{
register int i;
register BYTE *p;
p = ram + IY + data;
i = *p & 128;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
*p |= i;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}
static int op_srliyd(int data) /* SRL (IY+d) */
{
register BYTE *p;
p = ram + IY + data;
(*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG);
*p >>= 1;
F &= ~(H_FLAG | N_FLAG);
(*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG);
(*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG);
(parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG);
return(23);
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,63 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0
* 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* This modul contains some commonly used functions
*/
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <termios.h>
#include "sim.h"
/*
* atoi for hexadecimal numbers
*/
int exatoi(char *str)
{
register int num = 0;
while (isxdigit(*str)) {
num *= 16;
if (*str <= '9')
num += *str - '0';
else
num += toupper(*str) - '7';
str++;
}
return(num);
}
/*
* Wait for a single keystroke without echo
*/
int getkey(void)
{
register int c;
struct termios old_term, new_term;
tcgetattr(0, &old_term);
new_term = old_term;
new_term.c_lflag &= ~(ICANON | ECHO);
new_term.c_cc[VMIN] = 1;
tcsetattr(0, TCSADRAIN, &new_term);
c = getchar();
tcsetattr(0, TCSADRAIN, &old_term);
return(c);
}

Binary file not shown.

View File

@@ -0,0 +1,184 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0
* 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* This modul contains all the global variables
*/
#include "sim.h"
/*
* CPU-Register
*/
BYTE A,B,C,D,E,H,L; /* Z80 primary registers */
int F; /* normaly 8-Bit, but int is faster */
WORD IX, IY;
BYTE A_,B_,C_,D_,E_,H_,L_; /* Z80 secoundary registers */
int F_;
BYTE *PC; /* Z80 programm counter */
BYTE *STACK; /* Z80 stackpointer */
BYTE I; /* Z80 interrupt register */
BYTE IFF; /* Z80 interrupt flags */
long R; /* Z80 refresh register */
/* is normaly a 8 bit register */
/* the 32 bits are used to measure the */
/* clock frequency */
/*
* Variables for memory of the emulated CPU
*/
BYTE ram[65536L]; /* 64KB RAM */
BYTE *wrk_ram; /* workpointer into memory for dump etc. */
/*
* Variables for history memory
*/
#ifdef HISIZE
struct history his[HISIZE]; /* memory to hold trace informations */
int h_next; /* index into trace memory */
int h_flag; /* flag for trace memory overrun */
#endif
/*
* Variables for breakpoint memory
*/
#ifdef SBSIZE
struct softbreak soft[SBSIZE]; /* memory to hold breakpoint informations */
int sb_next; /* index into breakpoint memory */
#endif
/*
* Variables for runtime measurement
*/
#ifdef WANT_TIM
long t_states; /* number of counted T states */
int t_flag; /* flag, 1 = on, 0 = off */
BYTE *t_start = ram + 65535; /* start address for measurement */
BYTE *t_end = ram + 65535; /* end address for measurement */
#endif
/*
* Flag to controll operation of simulation
*/
int s_flag; /* flag for -s option */
int l_flag; /* flag for -l option */
int m_flag; /* flag for -m option */
int x_flag; /* flag for -x option */
int i_flag; /* flag for -i option */
int f_flag; /* flag for -f option */
char xfn[LENCMD]; /* buffer for filename (option -x) */
int break_flag = 1; /* 1 = break at HALT, 0 = execute HALT */
int cpu_state; /* status of CPU emulation */
int cpu_error; /* error status of CPU emulation */
int int_type; /* type of interrupt */
float freq; /* CPU clock in usec */
int int_mode; /* CPU interrupt mode (IM 0, IM 1, IM 2) */
int cntl_c; /* flag for cntl-c entered */
int cntl_bs; /* flag for cntl-\ entered */
/*
* Table to get parrity as fast as possible
*/
int parrity[256] = {
0 /* 00000000 */, 1 /* 00000001 */, 1 /* 00000010 */,
0 /* 00000011 */, 1 /* 00000100 */, 0 /* 00000101 */,
0 /* 00000110 */, 1 /* 00000111 */, 1 /* 00001000 */,
0 /* 00001001 */, 0 /* 00001010 */, 1 /* 00001011 */,
0 /* 00001100 */, 1 /* 00001101 */, 1 /* 00001110 */,
0 /* 00001111 */, 1 /* 00010000 */, 0 /* 00010001 */,
0 /* 00010010 */, 1 /* 00010011 */, 0 /* 00010100 */,
1 /* 00010101 */, 1 /* 00010110 */, 0 /* 00010111 */,
0 /* 00011000 */, 1 /* 00011001 */, 1 /* 00011010 */,
0 /* 00011011 */, 1 /* 00011100 */, 0 /* 00011101 */,
0 /* 00011110 */, 1 /* 00011111 */, 1 /* 00100000 */,
0 /* 00100001 */, 0 /* 00100010 */, 1 /* 00100011 */,
0 /* 00100100 */, 1 /* 00100101 */, 1 /* 00100110 */,
0 /* 00100111 */, 0 /* 00101000 */, 1 /* 00101001 */,
1 /* 00101010 */, 0 /* 00101011 */, 1 /* 00101100 */,
0 /* 00101101 */, 0 /* 00101110 */, 1 /* 00101111 */,
0 /* 00110000 */, 1 /* 00110001 */, 1 /* 00110010 */,
0 /* 00110011 */, 1 /* 00110100 */, 0 /* 00110101 */,
0 /* 00110110 */, 1 /* 00110111 */, 1 /* 00111000 */,
0 /* 00111001 */, 0 /* 00111010 */, 1 /* 00111011 */,
0 /* 00111100 */, 1 /* 00111101 */, 1 /* 00111110 */,
0 /* 00111111 */, 1 /* 01000000 */, 0 /* 01000001 */,
0 /* 01000010 */, 1 /* 01000011 */, 0 /* 01000100 */,
1 /* 01000101 */, 1 /* 01000110 */, 0 /* 01000111 */,
0 /* 01001000 */, 1 /* 01001001 */, 1 /* 01001010 */,
0 /* 01001011 */, 1 /* 01001100 */, 0 /* 01001101 */,
0 /* 01001110 */, 1 /* 01001111 */, 0 /* 01010000 */,
1 /* 01010001 */, 1 /* 01010010 */, 0 /* 01010011 */,
1 /* 01010100 */, 0 /* 01010101 */, 0 /* 01010110 */,
1 /* 01010111 */, 1 /* 01011000 */, 0 /* 01011001 */,
0 /* 01011010 */, 1 /* 01011011 */, 0 /* 01011100 */,
1 /* 01011101 */, 1 /* 01011110 */, 0 /* 01011111 */,
0 /* 01100000 */, 1 /* 01100001 */, 1 /* 01100010 */,
0 /* 01100011 */, 1 /* 01100100 */, 0 /* 01100101 */,
0 /* 01100110 */, 1 /* 01100111 */, 1 /* 01101000 */,
0 /* 01101001 */, 0 /* 01101010 */, 1 /* 01101011 */,
0 /* 01101100 */, 1 /* 01101101 */, 1 /* 01101110 */,
0 /* 01101111 */, 1 /* 01110000 */, 0 /* 01110001 */,
0 /* 01110010 */, 1 /* 01110011 */, 0 /* 01110100 */,
1 /* 01110101 */, 1 /* 01110110 */, 0 /* 01110111 */,
0 /* 01111000 */, 1 /* 01111001 */, 1 /* 01111010 */,
0 /* 01111011 */, 1 /* 01111100 */, 0 /* 01111101 */,
0 /* 01111110 */, 1 /* 01111111 */,
1 /* 10000000 */, 0 /* 10000001 */, 0 /* 10000010 */,
1 /* 10000011 */, 0 /* 10000100 */, 1 /* 10000101 */,
1 /* 10000110 */, 0 /* 10000111 */, 0 /* 10001000 */,
1 /* 10001001 */, 1 /* 10001010 */, 0 /* 10001011 */,
1 /* 10001100 */, 0 /* 10001101 */, 0 /* 10001110 */,
1 /* 10001111 */, 0 /* 10010000 */, 1 /* 10010001 */,
1 /* 10010010 */, 0 /* 10010011 */, 1 /* 10010100 */,
0 /* 10010101 */, 0 /* 10010110 */, 1 /* 10010111 */,
1 /* 10011000 */, 0 /* 10011001 */, 0 /* 10011010 */,
1 /* 10011011 */, 0 /* 10011100 */, 1 /* 10011101 */,
1 /* 10011110 */, 0 /* 10011111 */, 0 /* 10100000 */,
1 /* 10100001 */, 1 /* 10100010 */, 0 /* 10100011 */,
1 /* 10100100 */, 0 /* 10100101 */, 0 /* 10100110 */,
1 /* 10100111 */, 1 /* 10101000 */, 0 /* 10101001 */,
0 /* 10101010 */, 1 /* 10101011 */, 0 /* 10101100 */,
1 /* 10101101 */, 1 /* 10101110 */, 0 /* 10101111 */,
1 /* 10110000 */, 0 /* 10110001 */, 0 /* 10110010 */,
1 /* 10110011 */, 0 /* 10110100 */, 1 /* 10110101 */,
1 /* 10110110 */, 0 /* 10110111 */, 0 /* 10111000 */,
1 /* 10111001 */, 1 /* 10111010 */, 0 /* 10111011 */,
1 /* 10111100 */, 0 /* 10111101 */, 0 /* 10111110 */,
1 /* 10111111 */, 0 /* 11000000 */, 1 /* 11000001 */,
1 /* 11000010 */, 0 /* 11000011 */, 1 /* 11000100 */,
0 /* 11000101 */, 0 /* 11000110 */, 1 /* 11000111 */,
1 /* 11001000 */, 0 /* 11001001 */, 0 /* 11001010 */,
1 /* 11001011 */, 0 /* 11001100 */, 1 /* 11001101 */,
1 /* 11001110 */, 0 /* 11001111 */, 1 /* 11010000 */,
0 /* 11010001 */, 0 /* 11010010 */, 1 /* 11010011 */,
0 /* 11010100 */, 1 /* 11010101 */, 1 /* 11010110 */,
0 /* 11010111 */, 0 /* 11011000 */, 1 /* 11011001 */,
1 /* 11011010 */, 0 /* 11011011 */, 1 /* 11011100 */,
0 /* 11011101 */, 0 /* 11011110 */, 1 /* 11011111 */,
1 /* 11100000 */, 0 /* 11100001 */, 0 /* 11100010 */,
1 /* 11100011 */, 0 /* 11100100 */, 1 /* 11100101 */,
1 /* 11100110 */, 0 /* 11100111 */, 0 /* 11101000 */,
1 /* 11101001 */, 1 /* 11101010 */, 0 /* 11101011 */,
1 /* 11101100 */, 0 /* 11101101 */, 0 /* 11101110 */,
1 /* 11101111 */, 0 /* 11110000 */, 1 /* 11110001 */,
1 /* 11110010 */, 0 /* 11110011 */, 1 /* 11110100 */,
0 /* 11110101 */, 0 /* 11110110 */, 1 /* 11110111 */,
1 /* 11111000 */, 0 /* 11111001 */, 0 /* 11111010 */,
1 /* 11111011 */, 0 /* 11111100 */, 1 /* 11111101 */,
1 /* 11111110 */, 0 /* 11111111 */
};

View File

@@ -0,0 +1,50 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0
* 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* Declaration of variables in simglb.c
*/
extern BYTE A,B,C,D,E,H,L,A_,B_,C_,D_,E_,H_,L_,*PC,*STACK,I,IFF;
extern WORD IX,IY;
extern int F,F_;
extern long R;
extern BYTE ram[],*wrk_ram;
extern int s_flag,l_flag,m_flag,x_flag,break_flag,i_flag,f_flag,
cpu_state, cpu_error,int_type,int_mode,cntl_c,cntl_bs,
parrity[],sb_next;
extern float freq;
extern char xfn[];
#ifdef HISIZE
extern struct history his[];
extern int h_next, h_flag;
#endif
#ifdef SBSIZE
extern struct softbreak soft[];
#endif
#ifdef WANT_TIM
extern long t_states;
extern int t_flag;
extern BYTE *t_start, *t_end;
#endif

Binary file not shown.

View File

@@ -0,0 +1,90 @@
/*
* Z80SIM - a Z80-CPU simulator
*
* Copyright (C) 1987-2006 by Udo Munk
*
* History:
* 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
* 11-JAN-89 Release 1.1
* 08-FEB-89 Release 1.2
* 13-MAR-89 Release 1.3
* 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30
* 20-DEC-90 Release 1.5 Ported to COHERENT 3.0
* 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2
* and some optimization
* 25-JUN-92 Release 1.7 comments in english
* 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's
*/
/*
* This module contain the interrupt handlers for the OS:
*
* int_on() : initialize interrupt handlers
* int_off() : reset interrupts to default
* user_int() : handler for user interrupt (CNTL-C)
* quit_int() : handler for signal "quit" (CNTL-\)
* term_int() : handler for signal SIGTERM when process is killed
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <signal.h>
#include "sim.h"
#include "simglb.h"
static void user_int(int), quit_int(int), term_int(int);
extern void exit_io(void), int_off();
extern struct termios old_term;
void int_on(void)
{
static struct sigaction newact;
newact.sa_handler = user_int;
sigaction(SIGINT, &newact, NULL);
newact.sa_handler = quit_int;
sigaction(SIGQUIT, &newact, NULL);
newact.sa_handler = term_int;
sigaction(SIGTERM, &newact, NULL);
}
void int_off(void)
{
static struct sigaction newact;
newact.sa_handler = SIG_DFL;
sigaction(SIGINT, &newact, NULL);
sigaction(SIGQUIT, &newact, NULL);
sigaction(SIGTERM, &newact, NULL);
}
static void user_int(int sig)
{
#ifdef CNTL_C
cpu_error = USERINT;
cpu_state = STOPPED;
#else
cntl_c++;
#endif
}
static void quit_int(int sig)
{
#ifdef CNTL_BS
cpu_error = USERINT;
cpu_state = STOPPED;
#else
cntl_bs++;
#endif
}
static void term_int(int sig)
{
exit_io();
int_off();
tcsetattr(0, TCSADRAIN, &old_term);
puts("\nKilled by user");
exit(0);
}

Binary file not shown.

BIN
emu/z80pack-1.9/z80sim/z80sim Executable file

Binary file not shown.