home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
EMULATOR
/
UNIX
/
CAIN2
/
DECODE.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-06-30
|
35KB
|
1,798 lines
/*
* execute()
*
* There are 256 possible opcodes. The switch statement selects one.
* $Header: /g/zmob/zrun/RCS/execute.c,v 1.1.1.5 84/04/19 17:51:14 bennet Exp $
*/
#include "cpm.h"
static byte partab[256]= /* Parity table, 1=even */
{
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,
};
#if 0
static byte setmask[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
static byte resmask[] = { ~1, ~2, ~4, ~8, ~16, ~32, ~64, ~128 };
#endif
int pop(void)
{
long r = ram[SP++];
return(r + (ram[SP++] << 8));
}
void push(int v)
{
ram[--SP] = v >> 8;
ram[--SP] = v & 0xff;
}
int decode(void)
{
byte *ptr;
long a, b, s, s1;
byte opcode = ram[PC++];
if (PC >= BDOS)
{
PC = pop();
return(0);
}
switch(opcode)
{
case 0: break; /* 00 NOP */
case 1: /* 01 LD BC,nn */
C = ram[PC++];
B = ram[PC++];
break;
case 2: /* 02 LD (BC),A */
ram[BC] = A; break;
case 3: /* 03 INC BC */
++BC; break;
case 4: /* 04 INC B */
HALF_CARRY = (lonyb(B) == 0xf);
++B;
SIGN = B >> 7;
ZERO = B == 0;
PARITY = B == 0x80;
BCD = 0;
break;
case 5: /* 05 DEC B */
HALF_CARRY = lonyb(B) != 0;
--B;
SIGN = B >> 7;
ZERO = B == 0;
PARITY = B == 0x7f;
BCD = 1;
break;
case 6: /* 06 LD B,n */
B = ram[PC++]; break;
case 7: /* 07 RLCA */
HALF_CARRY = BCD = 0;
CARRY = A >> 7;
A = (A << 1);
if (CARRY) ++A;
break;
case 8: /* 08 EX AF,AF' */
acc_bank = acc_bank ? 0 : 1; break;
case 9: /* 09 ADD HL,BC */
s = BC;
a = (HL & 0xfff) + (s & 0xfff);
s += HL;
HL = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 10: /* 0a LD A,(BC) */
A = ram[BC]; break;
case 11: /* 0b DEC BC */
--BC; break;
case 12: /* 0c INC C */
HALF_CARRY = lonyb(C) == 0xf;
++C;
SIGN = C >> 7;
ZERO = C == 0;
PARITY = C == 0x80;
BCD = 0;
break;
case 13: /* 0d DEC C */
HALF_CARRY = lonyb(C) != 0;
--C;
SIGN = C >> 7;
ZERO = C == 0;
PARITY = C == 0x7f;
BCD = 1;
break;
case 14: /* 0e LD C,n */
C = ram[PC++]; break;
case 15: /* 0f RRCA */
BCD = HALF_CARRY = 0;
CARRY = A;
A = (A >> 1) | (CARRY ? 128 : 0);
break;
case 16: /* 10 DJNZ e */
s = (signed char)(ram[PC++] + 1);
if (--B) PC += s;
break;
case 17: /* 11 LD DE,nn */
E = ram[PC++];
D = ram[PC++];
break;
case 18: /* 12 LD (DE),A */
ram[DE] = A; break;
case 19: /* 13 INC DE */
++DE; break;
case 20: /* 14 INC D */
HALF_CARRY = lonyb(D) == 0xf;
++D;
SIGN = D >> 7;
ZERO = D == 0;
PARITY = D == 0x80;
BCD = 0;
break;
case 21: /* 15 DEC D */
HALF_CARRY = lonyb(D) != 0;
--D;
SIGN = D >> 7;
ZERO = D == 0;
PARITY = D == 0x7f;
BCD = 1;
break;
case 22: /* 16 LD D,n */
D = ram[PC++]; break;
case 23: /* 17 RLA */
s = A << 1;
A = s | CARRY;
CARRY = s >> 8;
BCD = HALF_CARRY = 0;
break;
case 24: /* 18 JR e */
PC += (signed char)(ram[PC] + 1); break;
case 25: /* 19 ADD HL,DE */
s = DE;
a = (HL & 0xfff) + (s & 0xfff);
s += HL;
HL = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 26: /* 1a LD A,(DE) */
A = ram[DE]; break;
case 27: /* 1b DEC DE */
--DE; break;
case 28: /* 1c INC E */
HALF_CARRY = lonyb(E) == 0xf;
++E;
SIGN = E >> 7;
ZERO = E == 0;
PARITY = E == 0x80;
BCD = 0;
break;
case 29: /* 1d DEC E */
HALF_CARRY = lonyb(E) != 0;
--E;
SIGN = E >> 7;
ZERO = E == 0;
PARITY = E == 0x7f;
BCD = 1;
break;
case 30: /* 1e LD E,n */
E = ram[PC++];
break;
case 31: /* 1f RRA */
CARRY = (s = A | (CARRY << 8));
A = s >> 1;
BCD = HALF_CARRY = 0;
break;
case 32: /* 20 JR NZ,e */
if (ZERO) ++PC;
else PC += (signed char)(ram[PC] + 1);
break;
case 33: /* 21 LD HL,nn */
L = ram[PC++];
H = ram[PC++];
break;
case 34: /* 22 LD (nn),HL */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = L;
ram[TEMP + 1] = H;
break;
case 35: /* 23 INC HL */
++HL; break;
case 36: /* 24 INC H */
HALF_CARRY = lonyb(H) == 0xf;
++H;
SIGN = H >> 7;
ZERO = H == 0;
PARITY = H == 0x80;
BCD = 0;
break;
case 37: /* 25 DEC H */
HALF_CARRY = lonyb(H) != 0;
--H;
SIGN = H >> 7;
ZERO = H == 0;
PARITY = H == 0x7f;
BCD = 1;
break;
case 38: /* 26 LD H,n */
H = ram[PC++];
break;
case 39: /* 27 DAA */
s = A & 0x0f;
a = (A >> 4) & 0x0f;
s1 = 0;
if (BCD)
{
if (CARRY)
{
if (HALF_CARRY)
s1 = ((a > 5) && (s > 5)) ? 0x9a : 0;
else
s1 = ((a > 6) && (s < 10)) ? 0xa0 : 0;
}
else
if(HALF_CARRY)
s1 = ((a < 9) && (s > 5)) ? 0xfa : 0;
}
else
{
if (CARRY)
{
if(HALF_CARRY)
s1 = ((a < 4) && (s < 4)) ? 0x66 : 0;
else if (a < 3)
s1 = (s < 10) ? 0x60 : 0x66;
}
else
{
if(HALF_CARRY)
{
if (s < 4)
if (a > 9)
{
s1 = 0x66;
CARRY = 1;
}
else s1 = 0x06;
}
else
{
if ((a > 8) && (s > 9))
{
s1 = 0x66;
CARRY = 1;
}
else if ((a > 9) && (s < 10))
{
s1 = 0x60;
CARRY = 1;
}
else if ((a < 10) && (s < 10))
;
else if ((a < 9) && (s > 9))
s1 = 6;
}
}
}
HALF_CARRY = ((int)(A) + (int)(s1)) > 0xf;
A += s1;
SIGN = A >> 7;
ZERO = (A == 0);
PARITY = partab[A];
break;
case 40: /* 28 JR Z,e */
if (ZERO) PC += (signed char)(ram[PC] + 1);
else ++PC;
break;
case 41: /* 29 ADD HL,HL */
s = HL;
a = (HL & 0xfff) + (s & 0xfff);
s += HL;
HL = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 42: /* 2a LD HL,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
L = ram[TEMP];
H = ram[TEMP + 1];
break;
case 43: /* 2b DEC HL */
--HL; break;
case 44: /* 2c INC L */
HALF_CARRY = lonyb(L) == 0xf;
++L;
SIGN = L >> 7;
ZERO = L == 0;
PARITY = L == 0x80;
BCD = 0;
break;
case 45: /* 2d DEC L */
HALF_CARRY = lonyb(L) != 0;
--L;
SIGN = L >> 7;
ZERO = L == 0;
PARITY = L == 0x7f;
BCD = 1;
break;
case 46: /* 2e LD L,n */
L = ram[PC++];
break;
case 47: /* 2f CPL */
A = ~A;
HALF_CARRY = BCD = 1;
break;
case 48: /* 30 JR NC,e */
if(CARRY) ++PC;
else PC += (signed char)(ram[PC] + 1);
break;
case 49: /* 31 LD SP,nn */
SPL = ram[PC++];
SPH = ram[PC++];
break;
case 50: /* 32 LD (nn),A */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = A;
break;
case 51: /* 33 INC SP */
++SP; break;
case 52: /* 34 INC (HL) */
HALF_CARRY = lonyb(ram[HL]) == 0xf;
++ram[HL];
SIGN = ram[HL] >> 7;
ZERO = ram[HL] == 0;
PARITY = ram[HL] == 0x80;
BCD = 0;
break;
case 53: /* 35 DEC (HL) */
HALF_CARRY = lonyb(ram[HL]) != 0;
--ram[HL];
SIGN = ram[HL] >> 7;
ZERO = ram[HL] == 0;
PARITY = ram[HL] == 0x7f;
BCD = 1;
break;
case 54: /* 36 LD (HL),n */
ram[HL] = ram[PC++]; break;
case 55: /* 37 SCF */
HALF_CARRY = BCD = 0;
CARRY = 1;
break;
case 56: /* 38 JR C,e */
if (CARRY) PC += (signed char)(ram[PC] + 1);
else ++PC;
break;
case 57: /* 39 ADD HL,SP */
s = SP;
a = (HL & 0xfff) + (s & 0xfff);
s += HL;
HL = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 58: /* 3a LD A,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
A = ram[TEMP];
break;
case 59: /* 3b DEC SP */
--SP; break;
case 60: /* 3c INC A */
HALF_CARRY = lonyb(A) == 0xf;
++A;
SIGN = A >> 7;
ZERO = A == 0;
PARITY = A == 0x80;
BCD = 0;
break;
case 61: /* 3d DEC A */
HALF_CARRY = lonyb(A) != 0;
--A;
SIGN = A >> 7;
ZERO = A == 0;
PARITY = A == 0x7f;
BCD = 1;
break;
case 62: /* 3e LD A,n */
A = ram[PC++]; break;
case 63: /* 3f CCF */
HALF_CARRY = CARRY;
CARRY = ~CARRY;
BCD = 0;
break;
case 64: /* 40 LD B,B */
break;
case 65: /* 41 LD B,C */
B = C; break;
case 66: /* 42 LD B,D */
B = D; break;
case 67: /* 43 LD B,E */
B = E; break;
case 68: /* 44 LD B,H */
B = H; break;
case 69: /* 45 LD B,L */
B = L; break;
case 70: /* 46 LD B, (HL) */
B = ram[HL]; break;
case 71: /* 47 LD B,A */
B = A; break;
case 72: /* 48 LD C,B */
C = B; break;
case 73: /* 49 LD C,C */
break;
case 74: /* 4a LD C,D */
C = D; break;
case 75: /* 4b LD C,E */
C = E; break;
case 76: /* 4c LD C,H */
C = H; break;
case 77: /* 4d LD C,L */
C = L; break;
case 78: /* 4e LD C, (HL) */
C = ram[HL]; break;
case 79: /* 4f LD C,A */
C = A; break;
case 80: /* 50 LD D,B */
D = B; break;
case 81: /* 51 LD D,C */
D = C; break;
case 82: /* 52 LD D,D */
break;
case 83: /* 53 LD D,E */
D = E; break;
case 84: /* 54 LD D,H */
D = H; break;
case 85: /* 55 LD D,L */
D = L; break;
case 86: /* 56 LD D, (HL) */
D = ram[HL]; break;
case 87: /* 57 LD D,A */
D = A; break;
case 88: /* 58 LD E,B */
E = B; break;
case 89: /* 59 LD E,C */
E = C; break;
case 90: /* 5a LD E,D */
E = D; break;
case 91: /* 5b LD E,E */
break;
case 92: /* 5c LD E,H */
E = H; break;
case 93: /* 5d LD E,L */
E = L; break;
case 94: /* 5e LD E, (HL) */
E = ram[HL]; break;
case 95: /* 5f LD E,A */
E = A; break;
case 96: /* 60 LD H,B */
H = B; break;
case 97: /* 61 LD H,C */
H = C; break;
case 98: /* 62 LD H,D */
H = D; break;
case 99: /* 63 LD H,E */
H = E; break;
case 100: /* 64 LD H,H */
break;
case 101: /* 65 LD H,L */
H = L; break;
case 102: /* 66 LD H, (HL) */
H = ram[HL]; break;
case 103: /* 67 LD H,A */
H = A; break;
case 104: /* 68 LD L,B */
L = B; break;
case 105: /* 69 LD L,C */
L = C; break;
case 106: /* 6a LD L,D */
L = D; break;
case 107: /* 6b LD L,E */
L = E; break;
case 108: /* 6c LD L,H */
L = H; break;
case 109: /* 6d LD L,L */
break;
case 110: /* 6e LD L,(HL) */
L = ram[HL]; break;
case 111: /* 6f LD L,A */
L = A; break;
case 112: /* 70 LD (HL),B */
ram[HL] = B; break;
case 113: /* 71 LD (HL),C */
ram[HL] = C; break;
case 114: /* 72 LD (HL),D */
ram[HL] = D; break;
case 115: /* 73 LD (HL),E */
ram[HL] = E; break;
case 116: /* 74 LD (HL),H */
ram[HL] = H; break;
case 117: /* 75 LD (HL),L */
ram[HL] = L; break;
case 118: /* 76 HALT */
return(0x76);
case 119: /* 77 LD (HL),A */
ram[HL] = A; break;
case 120: /* 78 LD A,B */
A = B; break;
case 121: /* 79 LD A,C */
A = C; break;
case 122: /* 7a LD A,D */
A = D; break;
case 123: /* 7b LD A,E */
A = E; break;
case 124: /* 7c LD A,H */
A = H; break;
case 125: /* 7d LD A,L */
A = L; break;
case 126: /* 7e LD A,(HL) */
A = ram[HL]; break;
case 127: /* 7f LD A,A */
break;
case 128: /* 80 ADD A,B */
s = B;
goto add;
case 129: /* 81 ADD A,C */
s = C;
goto add;
case 130: /* 82 ADD A,D */
s = D;
goto add;
case 131: /* 83 ADD A,E */
s = E;
goto add;
case 132: /* 84 ADD A,H */
s = H;
goto add;
case 133: /* 85 ADD A,L */
s = L;
goto add;
case 134: /* 86 ADD A,(HL) */
s = ram[HL];
goto add;
case 135: /* 87 ADD A,A */
s = A;
goto add;
case 136: /* 88 ADC A,B */
s = B;
goto adc;
case 137: /* 89 ADC A,C */
s = C;
goto adc;
case 138: /* 8a ADC A,D */
s = D;
goto adc;
case 139: /* 8b ADC A,E */
s = E;
goto adc;
case 140: /* 8c ADC A,H */
s = H;
goto adc;
case 141: /* 8d ADC A,L */
s = L;
goto adc;
case 142: /* 8e ADC A,(HL) */
s = ram[HL];
goto adc;
case 143: /* 8f ADC A,A */
s = A;
adc:
a = A & 0x0f;
s1 = s & 0x0f;
if (CARRY) { s++; a++; }
goto add1;
add:
a = A & 0x0f;
s1 = s & 0x0f;
add1:
b = A & 0x80;
BCD = 0;
s += A;
A = s;
a += s1;
PARITY = (A & 0x80) == b ? 0 : 1;
set_flags:
CARRY = s >> 8;
HALF_CARRY = a >> 4;
SIGN = s >> 7;
ZERO = s ? 0 : 1;
break;
case 144: /* 90 SUB A,B */
s = B;
goto sub;
case 145: /* 91 SUB A,C */
s = C;
goto sub;
case 146: /* 92 SUB A,D */
s = D;
goto sub;
case 147: /* 93 SUB A,E */
s = E;
goto sub;
case 148: /* 94 SUB A,H */
s = H;
goto sub;
case 149: /* 95 SUB A,L */
s = L;
goto sub;
case 150: /* 96 SUB A,(HL) */
s = ram[HL];
goto sub;
case 151: /* 97 SUB A,A */
s = A;
goto sub;
case 152: /* 98 SBC A,B */
s = B;
goto sbc;
case 153: /* 99 SBC A,C */
s = C;
goto sbc;
case 154: /* 9a SBC A,D */
s = D;
goto sbc;
case 155: /* 9b SBC A,E */
s = E;
goto sbc;
case 156: /* 9c SBC A,H */
s = H;
goto sbc;
case 157: /* 9d SBC A,L */
s = L;
goto sbc;
case 158: /* 9e SBC A,(HL) */
s = ram[HL];
goto sbc;
case 159: /* 9f SBC A,A */
s = A;
sbc:
a = A & 0x0f;
s1 = s & 0x0f;
if (CARRY) { s--; a--; }
goto sub1;
sub:
a = A & 0x0f;
s1 = s & 0x0f;
sub1:
b = A & 0x80;
s = A - s;
A = s;
a -= s1;
BCD = 1;
PARITY = (A & 0x80) == b ? 0 : 1;
goto set_flags;
case 160: /* a0 AND A,B */
s = B;
goto and;
case 161: /* a1 AND A,C */
s = C;
goto and;
case 162: /* a2 AND A,D */
s = D;
goto and;
case 163: /* a3 AND A,E */
s = E;
goto and;
case 164: /* a4 AND A,H */
s = H;
goto and;
case 165: /* a5 AND A,L */
s = L;
goto and;
case 166: /* a6 AND A,(HL) */
s = ram[HL];
goto and;
case 167: /* a7 AND A,A */
s = A;
and:
a = A & 0x0f;
s1 = s & 0x0f;
s &= A;
A = s;
a &= s;
PARITY = partab[A];
goto set_flags;
case 168: /* a8 XOR A,B */
s = B;
goto xor;
case 169: /* a9 XOR A,C */
s = C;
goto xor;
case 170: /* aa XOR A,D */
s = D;
goto xor;
case 171: /* ab XOR A,E */
s = E;
goto xor;
case 172: /* ac XOR A,H */
s = H;
goto xor;
case 173: /* ad XOR A,L */
s = L;
goto xor;
case 174: /* ae XOR A,(HL) */
s = ram[HL];
goto xor;
case 175: /* af XOR A,A */
s = A;
xor:
a = A & 0x0f;
s1 = s & 0x0f;
s ^= A;
A = s;
a ^= s;
PARITY = partab[A];
goto set_flags;
case 176: /* b1 OR B */
s = B;
goto or;
case 177: /* b1 OR C */
s = C;
goto or;
case 178: /* b2 OR D */
s = D;
goto or;
case 179: /* b3 OR E */
s = E;
goto or;
case 180: /* b4 OR H */
s = H;
goto or;
case 181: /* b5 OR L */
s = L;
goto or;
case 182: /* b6 OR (HL) */
s = ram[HL];
goto or;
case 183: /* b7 OR A */
s = A;
or:
a = A & 0x0f;
s1 = s & 0x0f;
s |= A;
A = s;
a |= s;
PARITY = partab[A];
goto set_flags;
case 184: /* b8 CP B */
s = B;
goto cp;
case 185: /* b9 CP C */
s = C;
goto cp;
case 186: /* ba CP D */
s = D;
goto cp;
case 187: /* bb CP E */
s = E;
goto cp;
case 188: /* bc CP H */
s = H;
goto cp;
case 189: /* bd CP L */
s = L;
goto cp;
case 190: /* be CP (HL) */
s = ram[HL];
goto cp;
case 191: /* bf CP A */
s = A;
cp:
a = A & 0x0f;
s1 = s & 0x0f;
s = A - s;
a -= s1;
BCD = 1;
goto set_flags;
case 192: /* c0 RET NZ */
if (!ZERO) PC = pop(); break;
case 193: /* c1 POP BC */
BC = pop(); break;
case 194: /* c2 JP NZ,nn */
if (ZERO) { PC += 2; break;}
case 195: /* c3 JP nn */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
break;
case 196: /* c4 CALL NZ,nn */
if (ZERO) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
break;
case 197: /* c5 PUSH BC */
push(BC); break;
case 198: /* c6 ADD A,n */
s = ram[PC++];
goto add;
case 199: /* c7 RST 0 */
push(PC);
PC = 0;
break;
case 200: /* c8 RET Z */
if (!ZERO) break;
case 201: /* c9 RET */
PC = pop();
break;
case 202: /* ca JP Z,nn */
if (ZERO)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
else PC += 2;
break;
case 203: /* cb oh boy */
switch (ram[PC] & 0x03)
{
case 0: ptr = &B;
case 1: ptr = &C;
case 2: ptr = &D;
case 3: ptr = &E;
case 4: ptr = &H;
case 5: ptr = &L;
case 6: ptr = ram + HL;
case 7: ptr = &A;
default: ptr = (void *)(0);
}
cb_stuff:
if ((s1 = ((s = ram[PC++]) & 0xc0)) != 0)
{
a = 1 << ((s & 0x3f) >> 3);
switch (s1)
{
case 0x40: /* BIT */
ZERO = *ptr & a;
HALF_CARRY = 1;
BCD = 0;
break;
case 0x80: /* RES */
*ptr &= ~a;
break;
case 0xb0: /* SET */
*ptr |= a;
break;
}
}
else
{
switch (s & 0xf8)
{
case 0x00: /* RLC */
CARRY= *ptr >> 7;
*ptr <<= 1;
if (CARRY) ++*ptr;
break;
case 0x08: /* RRC */
CARRY = *ptr;
*ptr >>= 1;
if (CARRY) *ptr |= 0x80;
break;
case 0x10: /* RL */
a = CARRY;
CARRY = *ptr >> 7;
*ptr <<= 1;
*ptr += a;
break;
case 0x18: /* RR */
a = CARRY;
CARRY = *ptr;
*ptr >>= 1;
if (a) *ptr |= 0x80;
break;
case 0x20: /* SLA */
CARRY = *ptr >> 7;
*ptr <<= 1;
break;
case 0x28: /* SRA */
CARRY = *ptr;
*ptr >>= 1;
if (*ptr & 0x40) *ptr |= 0x80;
break;
case 0x30: /* SLL ???? Oh well. It fits */
CARRY = *ptr >> 7;
*ptr <<= 1;
*ptr |= 1;
break;
case 0x38: /* SRL */
CARRY = *ptr;
*ptr >>= 1;
}
SIGN = *ptr >> 7;
ZERO = *ptr == 0;
HALF_CARRY = BCD = 0;
PARITY = partab[*ptr];
}
break;
case 204: /* cc CALL Z,nn */
if (ZERO)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
else PC += 2;
break;
case 205: /* cd CALL nn */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
break;
case 206: /* ce ADC A,n */
s = ram[PC++];
goto adc;
case 207: /* cf RST 08 */
push(PC);
PC = 8;
break;
case 208: /* d0 RET NC */
if (!CARRY)
PC = pop();
break;
case 209: /* d1 POP DE */
DE = pop();
break;
case 210: /* d2 JP NC,nn */
if (CARRY) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
break;
case 211: /* d3 OUT (n),A */
return(211);
case 212: /* d4 CALL NC,nn */
if (CARRY) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
break;
case 213: /* d5 PUSH DE */
push(DE); break;
case 214: /* d6 SUB N */
s = ram[PC++];
goto sub;
case 215: /* d7 RST 10 */
push(PC);
PC = 16;
break;
case 216: /* d8 RET C */
if (CARRY)
PC = pop();
break;
case 217: /* d9 EXX */
gr_bank = gr_bank ? 0 : 1; break;
case 218: /* da JP C,nn */
if (CARRY)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
else PC += 2;
break;
case 219: /* db IN A,(n) */
return(219);
case 220: /* dc CALL C,nn */
if (CARRY)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
else PC += 2;
break;
case 221: /* DD instructions - use IX register */
opcode = ram[PC++];
switch (opcode)
{
case 0x09: /* 09 ADD IX,BC */
s = BC;
a = (IX & 0xfff) + (s & 0xfff);
s += IX;
IX = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x19: /* ADD IX, DE */
s = DE;
a = (IX & 0xfff) + (s & 0xfff);
s += IX;
IX = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x21: /* LD IX, nn */
IXL = ram[PC++];
IXH = ram[PC++];
break;
case 0x22: /* LD (nn), IX) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = IXL;
ram[TEMP + 1] = IXH;
break;
case 0x23: /* INC IX */
IX++; break;
case 0x29: /* ADD IX, IX */
s = IX;
a = (IX & 0xfff) + (s & 0xfff);
s += IX;
IX = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x2a: /* LD IX, (nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
IXL = ram[TEMP];
IXH = ram[TEMP + 1];
break;
case 0x2b: /* DEC IX */
IX--; break;
case 0x34: /* INC (IX + d) */
ptr = ram + IX + ram[PC++];
HALF_CARRY = lonyb(*ptr) == 0xf;
++(*ptr);
SIGN = *ptr >> 7;
ZERO = *ptr == 0;
PARITY = *ptr == 0x80;
BCD = 0;
break;
case 0x35: /* DEC (IX + d) */
ptr = ram + IX + ram[PC++];
HALF_CARRY = lonyb(*ptr) != 0;
--(*ptr);
SIGN = *ptr >> 7;
ZERO = *ptr == 0;
PARITY = *ptr == 0x7f;
BCD = 1;
break;
case 0x36: /* LD (IX + d), n */
TEMP = IX + ram[PC++];
ram[TEMP] = ram[PC++];
break;
case 0x39: /* ADD IX, SP */
s = SP;
a = (IX & 0xfff) + (s & 0xfff);
s += IX;
IX = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x46: /* LD B, (IX + d) */
B = ram[IX + ram[PC++]]; break;
case 0x4e: /* LD C, (IX + d) */
C = ram[IX + ram[PC++]]; break;
case 0x56: /* LD D, (IX + d) */
D = ram[IX + ram[PC++]]; break;
case 0x5e: /* LD E, (IX + d) */
E = ram[IX + ram[PC++]]; break;
case 0x66: /* LD H, (IX + d) */
H = ram[IX + ram[PC++]]; break;
case 0x6e: /* LD L, (IX + d) */
L = ram[IX + ram[PC++]]; break;
case 0x70: /* LD (IX + d, B */
ram[IX + ram[PC++]] = B; break;
case 0x71: /* LD (IX + d, C */
ram[IX + ram[PC++]] = C; break;
case 0x72: /* LD (IX + d, D */
ram[IX + ram[PC++]] = D; break;
case 0x73: /* LD (IX + d, E */
ram[IX + ram[PC++]] = E; break;
case 0x74: /* LD (IX + d, H */
ram[IX + ram[PC++]] = H; break;
case 0x75: /* LD (IX + d, L */
ram[IX + ram[PC++]] = L; break;
case 0x77: /* LD (IX + d, A */
ram[IX + ram[PC++]] = A; break;
case 0x7e: /* LD A, (IX + d) */
A = ram[IX + ram[PC++]]; break;
case 0x86: /* ADD A, (IX + d) */
s = ram[IX + ram[PC++]];
goto add;
case 0x8e: /* ADC A, (IX + d) */
s = ram[IX + ram[PC++]];
goto adc;
case 0x96: /* SUB A, (IX + d) */
s = ram[IX + ram[PC++]];
goto sub;
case 0x9e: /* SBC A, (IX + d) */
s = ram[IX + ram[PC++]];
goto sbc;
case 0xa6: /* AND A, (IX + d) */
s = ram[IX + ram[PC++]];
goto and;
case 0xae: /* XOR A, (IX + d) */
s = ram[IX + ram[PC++]];
goto xor;
case 0xb6: /* OR A, (IX + d) */
s = ram[IX + ram[PC++]];
goto or;
case 0xbe: /* CP A, (IX + d) */
s = ram[IX + ram[PC++]];
goto cp;
case 0xcb:
ptr = ram + IX + ram[PC++];
goto cb_stuff;
case 0xe1: /* POP IX */
IX = pop(); break;
case 0xe3: /* EX (SP), IX */
s = IX;
IX = pop();
push(s);
break;
case 0xe5: /* PUSH IX */
push(IX); break;
case 0xe9: /* JP (IX) */
PC = IX; break;
case 0xf9: /* LD SP, IX */
SP = IX;
break; default: return(-1);
}
break;
case 222: /* de SBC A,n */
s = ram[PC++];
goto sbc;
case 223: /* df RST 18 */
push(PC);
PC = 0x18;
break;
case 224: /* e0 RET PO */
if (!PARITY)
PC = pop();
break;
case 225: /* e1 POP HL */
HL = pop(); break;
case 226: /* e2 JP PO,nn */
if (PARITY) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
break;
case 227: /* e3 EX (SP),HL */
s = HL;
HL = pop();
push(s);
break;
case 228: /* e4 CALL PO,nn */
if (PARITY) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
break;
case 229: /* e5 PUSH HL */
push(HL); break;
case 230: /* e6 AND n */
s = ram[PC++];
goto and;
case 231: /* e7 RST 20 */
push(PC);
PC = 0x20;
break;
case 232: /* e8 RET PE */
if (PARITY)
PC = pop();
break;
case 233: /* e9 JP (HL) */
PC = HL; break;
case 234: /* ea JP PE,nn */
if (PARITY)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
else PC += 2;
break;
case 235: /* eb EX DE,HL */
s = HL;
HL = DE;
DE = s;
break;
case 236: /* ec CALL PE,nn */
if (PARITY)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
break;
case 237: /* ed oh boy */
a = ram[PC++];
switch(a)
{
case 0x40: /* IN B,(C) */
case 0x41: /* OUT (C),B */
case 0x48: /* IN C,(C) */
case 0x49: /* OUT (C),C */
case 0x50: /* IN D,(C) */
case 0x51: /* OUT (C),D */
case 0x58: /* IN E,(C) */
case 0x59: /* OUT (C),E */
case 0x60: /* IN H,(C) */
case 0x61: /* OUT (C),H */
case 0x68: /* IN L,(C) */
case 0x69: /* OUT (C),L */
case 0x78: /* IN A,(C) */
case 0x79: /* OUT (C),A */
case 0xa2: /* INI */
case 0xa3: /* OUTI */
case 0xaa: /* IND */
case 0xab: /* OUTD */
case 0xb2: /* INIR */
case 0xb3: /* OTIR */
case 0xba: /* INDR */
case 0xbb: /* OTDR */
return(0xed00 + a);
case 0x42: /* SBC HL,BC */
TEMP = BC;
goto edsbc;
case 0x43: /* LD (nn),BC */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = C;
ram[TEMP + 1] = B;
break;
case 0x44: /* NEG */
HALF_CARRY = lonyb(A) != 0;
CARRY = A!= 0;
PARITY = A == 0x80;
A = 0 - A;
SIGN = A >> 7;
ZERO = A == 0;
BCD = 1;
break;
case 0x45: /* RETN */
/*
* INTERRUPT: Add restore IFF states
*/
PC = pop();
break;
case 0x46: /* IM 0 */
/*
* INTERRUPT: Set IM 0
*/
break;
case 0x47: /* LD I,A */
/*
* INTERRUPT: Load I from A
*/
break;
case 0x4a: /* ADC HL,BC */
TEMP = BC;
goto edadc;
case 0x4b: /* LD BC,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
C = ram[TEMP];
B = ram[TEMP + 1];
break;
case 0x4d: /* RETI */
PC = pop(); break;
case 0x4f: /* LD R,A */
R = A + 1; break;
case 0x52: /* SBC HL,DE */
TEMP = DE;
goto edsbc;
case 0x53: /* LD (nn),DE */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = E;
ram[TEMP + 1] = D;
break;
case 0x56: /* IM 1 */
/*
* INTERRUPT: Set IM 1
*/
break;
case 0x57: /* LD A,I */
/*
* INTERRUPT: A=I
*/
break;
case 0x5a: /* ADC HL,DE */
TEMP = DE;
goto edadc;
case 0x5b: /* LD DE,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
E = ram[TEMP];
D = ram[TEMP + 1];
break;
case 0x5e: /* IM 2 */
/*
* INTERRUPT: Set IM 2
*/
break;
case 0x5f: /* LD A,R */
A = ++R;
SIGN = A >> 7;
ZERO = A == 0;
HALF_CARRY = BCD = 0;
/*
* INTERRUPT: Copy IFF2 into PARITY
*/
PARITY = 0; break;
case 0x62: /* SBC HL,HL */
TEMP = HL;
goto edsbc;
case 0x63: /* LD (nn),HL */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = L;
ram[TEMP + 1] = H;
break;
case 0x67: /* RRD */
s = lonyb(ram[HL]);
HL = (ram[HL] >> 4) | (lonyb(A) << 4);
A = (A & 0xf0) | s;
SIGN = A >> 7;
ZERO = A == 0;
PARITY = partab[A];
HALF_CARRY = BCD = 0;
break;
case 0x6a: /* ADC HL,HL */
TEMP = HL;
goto edadc;
case 0x6b: /* LD HL,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
L = ram[TEMP];
H = ram[TEMP + 1];
break;
case 0x6f: /* RLD */
s = hinyb(ram[HL]);
ram[HL] = (ram[HL] << 4) | lonyb(A);
A = ( A & 0xf0) | s;
SIGN = A >> 7;
ZERO = A == 0;
PARITY = partab[A];
HALF_CARRY = BCD = 0;
break;
case 0x72: /* SBC HL,SP */
TEMP = SP;
edsbc:
s = (HL & 0xfff) - (TEMP & 0xfff);
if (CARRY) --s;
HALF_CARRY = s < 0;
s = (int)(HL - TEMP);
if (CARRY) --s;
PARITY = s < -32768 || s > 32767;
s = (int)(HL - TEMP);
if (CARRY) --s;
CARRY = s < 0;
HL = s;
SIGN =HL >> 15;
ZERO = HL == 0;
BCD = 1;
break;
case 0x73: /* LD (nn),SP */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = SPL;
ram[TEMP + 1] = SPH;
break;
case 0x7a: /* ADC HL,SP */
TEMP = SP;
edadc:
s = (HL & 0xfff) + (TEMP & 0xfff);
if (CARRY) ++s;
HALF_CARRY = s > 0xfff;
s = (int)(HL + TEMP);
if (CARRY) ++s;
s1 = s > 0xffff;
s = (int)(HL + TEMP);
if (CARRY) ++s;
PARITY = s < -32768 || s > 32767;
HL = s;
CARRY = s1;
SIGN = HL >> 15;
ZERO = HL == 0;
BCD = 0;
break;
case 0x7b: /* LD SP,(nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
SPL = ram[TEMP];
SPH = ram[TEMP + 1];
break;
case 0xa0: /* LDI */
ram[DE++] = ram[HL++];
PARITY = --BC != 0;
HALF_CARRY = BCD = 0;
break;
case 0xa1: /* CPI */
s = ram[HL++];
PARITY= --BC!=0;
ZERO = A == s;
HALF_CARRY = (int)((A & 0xf) - (s & 0xf)) < 0;
s = A - s;
SIGN = s >> 7;
BCD = 0;
break;
case 0xa8: /* LDD */
ram[DE--] = ram[HL--];
PARITY = --BC != 0;
HALF_CARRY = BCD = 0;
break;
case 0xa9: /* CPD */
s = ram[HL--];
PARITY = --BC != 0;
ZERO = A == s;
HALF_CARRY = (int)((A & 0xf) - (s & 0xf)) < 0;
s = A - s;
SIGN = s >> 7;
BCD = 0;
break;
case 0xb0: /* LDIR */
do
ram[DE++] = ram[HL++];
while (--BC);
HALF_CARRY = BCD = PARITY = 0;
break;
/*
* INTERRUPT: Convert for PC-=2
* Also conv CPIR,INIR,OTIR,LDDR,CPDR, etc
*/
case 0xb1: /* CPIR */
do
{
s = ram[HL++];
PARITY = --BC != 0;
ZERO = A == s;
} while(!ZERO && PARITY);
HALF_CARRY = (int)((A & 0xf) - (s & 0xf)) < 0;
s = A - s;
SIGN = s >> 7;
BCD = 0;
break;
case 0xb8: /* LDDR */
do
ram[DE--] = ram[HL--];
while (--BC);
HALF_CARRY = BCD = PARITY = 0;
break;
case 0xb9: /* CPDR */
do
{
s = ram[HL--];
PARITY = --BC != 0;
ZERO = A == s;
} while(!ZERO && PARITY);
HALF_CARRY = (int)((A & 0xf) - (s & 0xf)) < 0;
s = A - s;
SIGN = s >> 7;
BCD = 0;
}
break;
case 238: /* ee XOR n */
s = ram[PC++];
goto xor;
case 239: /* ef RST 28 */
push(PC);
PC = 0x28;
break;
case 240: /* f0 RET P */
if (!SIGN)
PC = pop();
break;
case 241: /* f1 POP AF */
AF = pop(); break;
case 242: /* f2 JP P,nn */
if (SIGN) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
break;
case 243: /* f3 DI */
/*
* INTERRUPT: Disable
*/
break;
case 244: /* f4 CALL P,nn */
if (SIGN) PC += 2;
else
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
break;
case 245: /* f5 PUSH AF */
push(AF); break;
case 246: /* f6 OR n */
s = ram[PC++];
goto or;
case 247: /* f7 RST 30 */
push(PC);
PC = 0x30;
break;
case 248: /* f8 RET M */
if (SIGN)
PC = pop();
break;
case 249: /* f9 LD SP,HL */
SP = HL; break;
case 250: /* fa JP M,nn */
if (SIGN)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
PC = TEMP;
}
else PC += 2;
break;
case 251: /* fb EI */
/*
* INTERRUPT: Enable
*/
break;
case 252: /* fc CALL M,nn */
if (SIGN)
{
TEMPL = ram[PC++];
TEMPH = ram[PC++];
push(PC);
PC = TEMP;
}
else PC += 2;
break;
case 253: /* FD instructions - use IY register */
opcode = ram[PC++];
switch (opcode)
{
case 0x09: /* 09 ADD IY,BC */
s = BC;
a = (IY & 0xfff) + (s & 0xfff);
s += IY;
IY = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x19: /* ADD IY, DE */
s = DE;
a = (IY & 0xfff) + (s & 0xfff);
s += IY;
IY = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x21: /* LD IY, nn */
IYL = ram[PC++];
IYH = ram[PC++];
break;
case 0x22: /* LD (nn), IY) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
ram[TEMP] = IYL;
ram[TEMP + 1] = IYH;
break;
case 0x23: /* INC IY */
IY++; break;
case 0x29: /* ADD IY, IY */
s = IY;
a = (IY & 0xfff) + (s & 0xfff);
s += IY;
IY = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x2a: /* LD IY, (nn) */
TEMPL = ram[PC++];
TEMPH = ram[PC++];
IYL = ram[TEMP];
IYH = ram[TEMP + 1];
break;
case 0x2b: /* DEC IY */
IY--; break;
case 0x34: /* INC (IY + d) */
ptr = ram + IY + ram[PC++];
HALF_CARRY = lonyb(*ptr) == 0xf;
++(*ptr);
SIGN = *ptr >> 7;
ZERO = *ptr == 0;
PARITY = *ptr == 0x80;
BCD = 0;
break;
case 0x35: /* DEC (IY + d) */
ptr = ram + IY + ram[PC++];
HALF_CARRY = lonyb(*ptr) != 0;
--(*ptr);
SIGN = *ptr >> 7;
ZERO = *ptr == 0;
PARITY = *ptr == 0x7f;
BCD = 1;
break;
case 0x36: /* LD (IY + d), n */
TEMP = IY + ram[PC++];
ram[TEMP] = ram[PC++];
break;
case 0x39: /* ADD IY, SP */
s = SP;
a = (IY & 0xfff) + (s & 0xfff);
s += IY;
IY = s;
BCD = 0;
CARRY = s >> 16;
HALF_CARRY = a >> 12;
break;
case 0x46: /* LD B, (IY + d) */
B = ram[IY + ram[PC++]]; break;
case 0x4e: /* LD C, (IY + d) */
C = ram[IY + ram[PC++]]; break;
case 0x56: /* LD D, (IY + d) */
D = ram[IY + ram[PC++]]; break;
case 0x5e: /* LD E, (IY + d) */
E = ram[IY + ram[PC++]]; break;
case 0x66: /* LD H, (IY + d) */
H = ram[IY + ram[PC++]]; break;
case 0x6e: /* LD L, (IY + d) */
L = ram[IY + ram[PC++]]; break;
case 0x70: /* LD (IY + d, B */
ram[IY + ram[PC++]] = B; break;
case 0x71: /* LD (IY + d, C */
ram[IY + ram[PC++]] = C; break;
case 0x72: /* LD (IY + d, D */
ram[IY + ram[PC++]] = D; break;
case 0x73: /* LD (IY + d, E */
ram[IY + ram[PC++]] = E; break;
case 0x74: /* LD (IY + d, H */
ram[IY + ram[PC++]] = H; break;
case 0x75: /* LD (IY + d, L */
ram[IY + ram[PC++]] = L; break;
case 0x77: /* LD (IY + d, A */
ram[IY + ram[PC++]] = A; break;
case 0x7e: /* LD A, (IY + d) */
A = ram[IY + ram[PC++]]; break;
case 0x86: /* ADD A, (IY + d) */
s = ram[IY + ram[PC++]];
goto add;
case 0x8e: /* ADC A, (IY + d) */
s = ram[IY + ram[PC++]];
goto adc;
case 0x96: /* SUB A, (IY + d) */
s = ram[IY + ram[PC++]];
goto sub;
case 0x9e: /* SBC A, (IY + d) */
s = ram[IY + ram[PC++]];
goto sbc;
case 0xa6: /* AND A, (IY + d) */
s = ram[IY + ram[PC++]];
goto and;
case 0xae: /* XOR A, (IY + d) */
s = ram[IY + ram[PC++]];
goto xor;
case 0xb6: /* OR A, (IY + d) */
s = ram[IY + ram[PC++]];
goto or;
case 0xbe: /* CP A, (IY + d) */
s = ram[IY + ram[PC++]];
goto cp;
case 0xcb:
ptr = ram + IY + ram[PC++];
goto cb_stuff;
case 0xe1: /* POP IY */
IY = pop(); break;
case 0xe3: /* EX (SP), IY */
s = IY;
IY = pop();
push(s);
break;
case 0xe5: /* PUSH IY */
push(IY); break;
case 0xe9: /* JP (IY) */
PC = IY; break;
case 0xf9: /* LD SP, IY */
SP = IY;
break; default: return(-1);
}
break;
case 254: /* fe CP n */
s = ram[PC++];
goto cp;
case 255: /* ff RST 38 */
push(PC);
PC = 0x38;
default: return(-1);
}
return(0);
}