summaryrefslogtreecommitdiff
path: root/z80_decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'z80_decode.c')
-rw-r--r--z80_decode.c103
1 files changed, 31 insertions, 72 deletions
diff --git a/z80_decode.c b/z80_decode.c
index 036e34e..74a8c1f 100644
--- a/z80_decode.c
+++ b/z80_decode.c
@@ -4,8 +4,8 @@
Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
- Some of the opcode routines are based on the Z80 emulation from YAZE,
- Copyright (c) 1995 Frank D. Cringle.
+ Some of the opcode routines are based on the Z80 emulation from FUSE,
+ Copyright (c) 1999-2003 Philip Kendall
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,25 +36,6 @@ static const char ident[]="$Id$";
/* ---------------------------------------- TABLES AND INIT
*/
-static const unsigned char partab[256] = {
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
- 4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
-};
-
static Z80Byte PSZtable[512];
static Z80Byte SZtable[512];
static Z80Byte Ptable[512];
@@ -436,14 +417,14 @@ do { \
cpu->AF.b[LO]=CARRY|H_Z80; \
if ((REG)&(1<<B)) \
{ \
- cpu->AF.b[LO]|=Z_Z80; \
- cpu->AF.b[LO]|=P_Z80; \
+ if (B==7 && (REG&S_Z80)) cpu->AF.b[LO]|=S_Z80; \
+ if (B==5 && (REG&B5_Z80)) cpu->AF.b[LO]|=B5_Z80; \
+ if (B==3 && (REG&B3_Z80)) cpu->AF.b[LO]|=B3_Z80; \
} \
else \
{ \
- if (B==7) cpu->AF.b[LO]|=S_Z80; \
- else if (B==5) cpu->AF.b[LO]|=B5_Z80; \
- else if (B==3) cpu->AF.b[LO]|=B3_Z80; \
+ cpu->AF.b[LO]|=Z_Z80; \
+ cpu->AF.b[LO]|=P_Z80; \
} \
} while(0)
@@ -967,58 +948,31 @@ do { \
/* ---------------------------------------- DAA
*/
-/* This code based on the DAA opcode from YAZE, (c) Frank D. Cringle
+/* This code based on the DAA opcode from FUSE, (c) Philip Kendall
*/
static void DAA (Z80 *cpu)
{
- Z80Word AF,acu,temp,cbits;
+ Z80Byte add=0;
+ Z80Byte carry=CARRY;
- AF=cpu->AF.w;
- acu=cpu->AF.b[HI];
- temp=acu&0xf;
- cbits=CARRY;
+ if ((IS_H) || ((cpu->AF.b[HI] & 0x0f)>9)) add=6;
- if (IS_N) /* last operation was a subtract */
- {
- int hd = cbits || acu > 0x99;
- if (IS_H || (temp > 9)) /* adjust low digit */
- {
- if (temp > 5)
- {
- CLR(AF,H_Z80);
- }
+ if (carry || (cpu->AF.b[HI] > 0x9f)) add|=0x60;
- acu -= 6;
- acu &= 0xff;
- }
- if (hd) /* adjust high digit */
- acu -= 0x160;
+ if (cpu->AF.b[HI] > 0x99 ) carry=1;
+
+ if (IS_N)
+ {
+ SUB8(add);
}
- else /* last operation was an add */
+ else
{
- if (IS_H || (temp > 9)) /* adjust low digit */
- {
- if (temp>9)
- {
- SET(AF,H_Z80);
- }
- else
- {
- CLR(AF,H_Z80);
- }
- acu += 6;
- }
- if (cbits || ((acu & 0x1f0) > 0x90)) /* adjust high digit */
- acu += 0x60;
+ if ((cpu->AF.b[HI]>0x90) && ((cpu->AF.b[HI] & 0x0f)>9)) add|=0x60;
+ ADD8(add);
}
- cbits |= (acu >> 8) & 1;
- acu &= 0xff;
- AF = (acu << 8) | (acu & 0xa8) | ((acu == 0) << 6) |
- (AF & 0x12) | partab[acu] | cbits;
-
- cpu->AF.w=AF;
- SETHIDDEN(cpu->AF.b[HI]);
+ cpu->AF.b[LO] = (cpu->AF.b[LO] & ~(C_Z80|P_Z80))
+ | carry | Ptable[cpu->AF.b[HI]];
}
@@ -2034,9 +1988,12 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
*L=FETCH_BYTE;
break;
- case 0x2f: /* RRA */
+ case 0x2f: /* CPL */
TSTATE(4);
- RRA;
+ cpu->AF.b[HI]^=0xff;
+ SETFLAG(H_Z80);
+ SETFLAG(N_Z80);
+ SETHIDDEN(cpu->AF.b[HI]);
break;
case 0x30: /* JR NC,d */
@@ -2078,8 +2035,9 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0x37: /* SCF */
TSTATE(4);
- CLRFLAG(H_Z80);
- SETFLAG(C_Z80);
+ cpu->AF.b[LO]=(cpu->AF.b[LO]&(S_Z80|Z_Z80|P_Z80))
+ | C_Z80
+ | (cpu->AF.b[HI]&(B3_Z80|B5_Z80));
break;
case 0x38: /* JR C,d */
@@ -2125,6 +2083,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
CLRFLAG(H_Z80);
cpu->AF.b[LO]^=C_Z80;
+ SETHIDDEN(cpu->AF.b[HI]);
break;
LD_BLOCK(0x40,cpu->BC.b[HI],cpu->BC.b[HI])