summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2023-04-23 08:24:31 +0800
committerIan C <ianc@noddybox.co.uk>2023-04-23 08:24:31 +0800
commit1d1e0acb5b4494f7c1b041e24e5de4f0614a150b (patch)
treef43094ced9e4b3dae4e9912eef606a9c567c635e /include
parentef18a653053c30237a9aff27eea91d38bd308987 (diff)
Updated Z80 emulation
Diffstat (limited to 'include')
-rw-r--r--include/z80.h43
-rw-r--r--include/z80_config.h6
-rw-r--r--include/z80_private.h73
3 files changed, 97 insertions, 25 deletions
diff --git a/include/z80.h b/include/z80.h
index ef24fd0..c9bd107 100644
--- a/include/z80.h
+++ b/include/z80.h
@@ -56,20 +56,30 @@ typedef signed char Z80Relative;
typedef unsigned short Z80Word;
-/* A Z80 16-bit register. To access the HI/LO component use the indexes
- Z80_HI_WORD and Z80_LO_WORD which will be initialised once Z80Init has been
- called.
+/* A Z80 16-bit register made up of 2 8-bit registers.
*/
+#ifdef Z80_LITTLE_ENDIAN
+typedef struct
+{
+ Z80Byte lo;
+ Z80Byte hi;
+} Z80RegPair;
+#endif
+
+#ifdef Z80_BIG_ENDIAN
+typedef struct
+{
+ Z80Byte hi;
+ Z80Byte lo;
+} Z80RegPair;
+#endif
+
typedef union
{
Z80Word w;
- Z80Byte b[2];
+ Z80RegPair b;
} Z80Reg;
-extern int Z80_HI_WORD;
-extern int Z80_LO_WORD;
-
-
/* The processor
*/
struct Z80Private;
@@ -134,13 +144,23 @@ typedef int (*Z80Callback)(Z80 *cpu, Z80Val data);
*/
typedef enum
{
- eZ80_Instruction, /* data = no cycles since reset */
+ eZ80_Instruction, /* data = cycles as returned by Z80Cycles */
eZ80_EDHook, /* data = byte after ED opcode (only for NOP opcodes) */
eZ80_Halt, /* data = 1 halt raised, 0 halt cleared by int */
eZ80_RETI, /* data = ignored */
eZ80_NO_CALLBACK /* leave at end */
} Z80CallbackReason;
+/* Defines cycle timers
+*/
+typedef enum
+{
+ Z80_TIMER_1,
+ Z80_TIMER_2,
+ Z80_TIMER_3,
+ Z80_NO_TIMERS
+} Z80Timer;
+
/* Flags in the F register
*/
@@ -235,6 +255,11 @@ void Z80Exec(Z80 *cpu);
Z80Val Z80Cycles(Z80 *cpu);
void Z80ResetCycles(Z80 *cpu, Z80Val cycles);
+/* Timers that count in cycle counts
+*/
+Z80Val Z80GetTimer(Z80 *cpu, Z80Timer timer);
+void Z80SetTimer(Z80 *cpu, Z80Timer timer, Z80Val cycles);
+
/* Set address to label mappings for the disassembler
*/
diff --git a/include/z80_config.h b/include/z80_config.h
index 8d9ee79..4168dc3 100644
--- a/include/z80_config.h
+++ b/include/z80_config.h
@@ -37,6 +37,12 @@
#define ENABLE_DISASSEM
+/* Pick one of these as appropriate for your real CPU
+#define Z80_BIG_ENDIAN
+*/
+#define Z80_LITTLE_ENDIAN
+
+
/* Define this to enable the array-based memory model. In this mode
an externally visible Z80Byte array called Z80_MEMORY must be
defined. The macros RAMBOT and RAMTOP define the writable area of
diff --git a/include/z80_private.h b/include/z80_private.h
index 10cf97e..e3d721a 100644
--- a/include/z80_private.h
+++ b/include/z80_private.h
@@ -19,14 +19,14 @@
-------------------------------------------------------------------------
- $Id: z80_private.h 13 2006-10-12 16:38:57Z ianc $
+ $Id$
Private macros for Z80
*/
#ifndef Z80_PRIVATE_H
-#define Z80_PRIVATE_H "$Id: z80_private.h 13 2006-10-12 16:38:57Z ianc $"
+#define Z80_PRIVATE_H "$Id$"
#include "z80_config.h"
@@ -48,6 +48,8 @@ struct Z80Private
{
Z80Val cycle;
+ Z80Val timer[Z80_NO_TIMERS];
+
int halt;
Z80Byte shift;
@@ -69,6 +71,8 @@ struct Z80Private
Z80Callback callback[eZ80_NO_CALLBACK][MAX_PER_CALLBACK];
int last_cb;
+
+ Z80Reg memptr;
};
#define PRIV cpu->priv
@@ -114,18 +118,21 @@ extern Z80Byte Z80_MEMORY[];
#define B3_Z80 0x08
#define B5_Z80 0x20
+#define HIDDEN_Z80 (B3_Z80|B5_Z80)
#define SET(v,b) (v)|=b
#define CLR(v,b) (v)&=~(b)
-#define SETFLAG(f) SET(cpu->AF.b[LO],f)
-#define CLRFLAG(f) CLR(cpu->AF.b[LO],f)
+#define SETFLAG(f) SET(cpu->AF.b.lo,f)
+#define CLRFLAG(f) CLR(cpu->AF.b.lo,f)
#ifdef ENABLE_ARRAY_MEMORY
#define PEEK(addr) Z80_MEMORY[addr]
+/* This can't be a macro as the macro is used as PEEKW(FETCH_WORD)
+*/
static inline Z80Word PEEKW(Z80Word addr)
{
return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8);
@@ -154,6 +161,9 @@ static inline Z80Word PEEKW(Z80Word addr)
#else
+Z80Word FPEEKW(Z80 *cpu, Z80Word addr);
+void FPOKEW(Z80 *cpu, Z80Word addr, Z80Word val);
+
#define PEEK(addr) (PRIV->mread(cpu,addr))
#define PEEKW(addr) FPEEKW(cpu,addr)
@@ -166,19 +176,37 @@ static inline Z80Word PEEKW(Z80Word addr)
#endif
-#define IS_C (cpu->AF.b[LO]&C_Z80)
-#define IS_N (cpu->AF.b[LO]&N_Z80)
-#define IS_P (cpu->AF.b[LO]&P_Z80)
-#define IS_H (cpu->AF.b[LO]&H_Z80)
-#define IS_Z (cpu->AF.b[LO]&Z_Z80)
-#define IS_S (cpu->AF.b[LO]&S_Z80)
+#define IS_C (cpu->AF.b.lo&C_Z80)
+#define IS_N (cpu->AF.b.lo&N_Z80)
+#define IS_P (cpu->AF.b.lo&P_Z80)
+#define IS_H (cpu->AF.b.lo&H_Z80)
+#define IS_Z (cpu->AF.b.lo&Z_Z80)
+#define IS_S (cpu->AF.b.lo&S_Z80)
#define CARRY IS_C
#define IS_IX_IY (PRIV->shift==0xdd || PRIV->shift==0xfd)
-#define OFFSET(off) off=(IS_IX_IY ? (Z80Relative)FETCH_BYTE:0)
-#define TSTATE(n) PRIV->cycle+=n
+#define OFFSET(base,off) do \
+ { \
+ if (IS_IX_IY) \
+ { \
+ off=(Z80Relative)FETCH_BYTE; \
+ PRIV->memptr.w=base+off; \
+ } \
+ else \
+ { \
+ off=0; \
+ } \
+ } while(0)
+
+#define TSTATE(n) do \
+ { \
+ PRIV->cycle+=n; \
+ PRIV->timer[Z80_TIMER_1]+=n; \
+ PRIV->timer[Z80_TIMER_2]+=n; \
+ PRIV->timer[Z80_TIMER_3]+=n; \
+ } while(0)
#define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f))
#define INC_R ADD_R(1)
@@ -211,19 +239,32 @@ static inline Z80Word PEEKW(Z80Word addr)
cpu->SP+=2; \
} while(0)
-#define SETHIDDEN(res) cpu->AF.b[LO]=(cpu->AF.b[LO]&~(B3_Z80|B5_Z80))|\
+#define SETHIDDEN(res) cpu->AF.b.lo=(cpu->AF.b.lo&~(B3_Z80|B5_Z80))|\
((res)&(B3_Z80|B5_Z80))
#define CALL do \
{ \
PUSH(cpu->PC+2); \
cpu->PC=PEEKW(cpu->PC); \
+ PRIV->memptr.w=cpu->PC; \
} while(0)
#define NOCALL cpu->PC+=2
-#define JP cpu->PC=PEEKW(cpu->PC)
-#define NOJP cpu->PC+=2
-#define JR cpu->PC+=(Z80Relative)PEEK(cpu->PC)+1
+
+#define JP do \
+ { \
+ cpu->PC=PEEKW(cpu->PC); \
+ PRIV->memptr.w=cpu->PC; \
+ } while(0)
+
+#define NOJP NOCALL
+
+#define JR do \
+ { \
+ cpu->PC+=(Z80Relative)PEEK(cpu->PC)+1; \
+ PRIV->memptr.w=cpu->PC; \
+ } while(0)
+
#define NOJR cpu->PC++
#define OUT(P,V) do \