1 |
/** Z80: portable Z80 emulator *******************************/ |
2 |
/** **/ |
3 |
/** Z80.h **/ |
4 |
/** **/ |
5 |
/** This file contains declarations relevant to emulation **/ |
6 |
/** of Z80 CPU. **/ |
7 |
/** **/ |
8 |
/** Copyright (C) Marat Fayzullin 1994-2007 **/ |
9 |
/** You are not allowed to distribute this software **/ |
10 |
/** commercially. Please, notify me, if you make any **/ |
11 |
/** changes to this file. **/ |
12 |
/*************************************************************/ |
13 |
#ifndef Z80_H |
14 |
#define Z80_H |
15 |
|
16 |
/* Compilation options: */ |
17 |
/* #define DEBUG */ /* Compile debugging version */ |
18 |
/* #define LSB_FIRST */ /* Compile for low-endian CPU */ |
19 |
/* #define MSB_FIRST */ /* Compile for hi-endian CPU */ |
20 |
|
21 |
/* LoopZ80() may return: */ |
22 |
#define INT_RST00 0x00C7 /* RST 00h */ |
23 |
#define INT_RST08 0x00CF /* RST 08h */ |
24 |
#define INT_RST10 0x00D7 /* RST 10h */ |
25 |
#define INT_RST18 0x00DF /* RST 18h */ |
26 |
#define INT_RST20 0x00E7 /* RST 20h */ |
27 |
#define INT_RST28 0x00EF /* RST 28h */ |
28 |
#define INT_RST30 0x00F7 /* RST 30h */ |
29 |
#define INT_RST38 0x00FF /* RST 38h */ |
30 |
#define INT_IRQ INT_RST38 /* Default IRQ opcode is FFh */ |
31 |
#define INT_NMI 0xFFFD /* Non-maskable interrupt */ |
32 |
#define INT_NONE 0xFFFF /* No interrupt required */ |
33 |
#define INT_QUIT 0xFFFE /* Exit the emulation */ |
34 |
|
35 |
/* Bits in Z80 F register: */ |
36 |
#define S_FLAG 0x80 /* 1: Result negative */ |
37 |
#define Z_FLAG 0x40 /* 1: Result is zero */ |
38 |
#define H_FLAG 0x10 /* 1: Halfcarry/Halfborrow */ |
39 |
#define P_FLAG 0x04 /* 1: Result is even */ |
40 |
#define V_FLAG 0x04 /* 1: Overflow occured */ |
41 |
#define N_FLAG 0x02 /* 1: Subtraction occured */ |
42 |
#define C_FLAG 0x01 /* 1: Carry/Borrow occured */ |
43 |
|
44 |
/* Bits in IFF flip-flops: */ |
45 |
#define IFF_1 0x01 /* IFF1 flip-flop */ |
46 |
#define IFF_IM1 0x02 /* 1: IM1 mode */ |
47 |
#define IFF_IM2 0x04 /* 1: IM2 mode */ |
48 |
#define IFF_2 0x08 /* IFF2 flip-flop */ |
49 |
#define IFF_EI 0x20 /* 1: EI pending */ |
50 |
#define IFF_HALT 0x80 /* 1: CPU HALTed */ |
51 |
|
52 |
/** Simple Datatypes *****************************************/ |
53 |
/** NOTICE: sizeof(byte)=1 and sizeof(word)=2 **/ |
54 |
/*************************************************************/ |
55 |
#ifndef BYTE_TYPE_DEFINED |
56 |
#define BYTE_TYPE_DEFINED |
57 |
typedef unsigned char byte; |
58 |
#endif |
59 |
#ifndef WORD_TYPE_DEFINED |
60 |
#define WORD_TYPE_DEFINED |
61 |
typedef unsigned short word; |
62 |
#endif |
63 |
typedef signed char offset; |
64 |
|
65 |
/** Structured Datatypes *************************************/ |
66 |
/** NOTICE: #define LSB_FIRST for machines where least **/ |
67 |
/** signifcant byte goes first. **/ |
68 |
/*************************************************************/ |
69 |
typedef union |
70 |
{ |
71 |
#ifdef LSB_FIRST |
72 |
struct { byte l,h; } B; |
73 |
#else |
74 |
struct { byte h,l; } B; |
75 |
#endif |
76 |
word W; |
77 |
} pair; |
78 |
|
79 |
typedef struct |
80 |
{ |
81 |
pair AF,BC,DE,HL,IX,IY,PC,SP; /* Main registers */ |
82 |
pair AF1,BC1,DE1,HL1; /* Shadow registers */ |
83 |
byte IFF,I; /* Interrupt registers */ |
84 |
byte R; /* Refresh register */ |
85 |
|
86 |
int IPeriod,ICount; /* Set IPeriod to number of CPU cycles */ |
87 |
/* between calls to LoopZ80() */ |
88 |
int IBackup; /* Private, don't touch */ |
89 |
word IRequest; /* Set to address of pending IRQ */ |
90 |
byte IAutoReset; /* Set to 1 to autom. reset IRequest */ |
91 |
byte TrapBadOps; /* Set to 1 to warn of illegal opcodes */ |
92 |
word Trap; /* Set Trap to address to trace from */ |
93 |
byte Trace; /* Set Trace=1 to start tracing */ |
94 |
void *User; /* Arbitrary user data (ID,RAM*,etc.) */ |
95 |
} Z80; |
96 |
|
97 |
/** ResetZ80() ***********************************************/ |
98 |
/** This function can be used to reset the registers before **/ |
99 |
/** starting execution with RunZ80(). It sets registers to **/ |
100 |
/** their initial values. **/ |
101 |
/*************************************************************/ |
102 |
void ResetZ80(register Z80 *R); |
103 |
|
104 |
/** ExecZ80() ************************************************/ |
105 |
/** This function will execute given number of Z80 cycles. **/ |
106 |
/** It will then return the number of cycles left, possibly **/ |
107 |
/** negative, and current register values in R. **/ |
108 |
/*************************************************************/ |
109 |
#ifdef EXECZ80 |
110 |
int ExecZ80(register Z80 *R,register int RunCycles); |
111 |
#endif |
112 |
|
113 |
/** IntZ80() *************************************************/ |
114 |
/** This function will generate interrupt of given vector. **/ |
115 |
/*************************************************************/ |
116 |
void IntZ80(register Z80 *R,register word Vector); |
117 |
|
118 |
/** RunZ80() *************************************************/ |
119 |
/** This function will run Z80 code until an LoopZ80() call **/ |
120 |
/** returns INT_QUIT. It will return the PC at which **/ |
121 |
/** emulation stopped, and current register values in R. **/ |
122 |
/*************************************************************/ |
123 |
#ifndef EXECZ80 |
124 |
word RunZ80(register Z80 *R); |
125 |
#endif |
126 |
|
127 |
/** RdZ80()/WrZ80() ******************************************/ |
128 |
/** These functions are called when access to RAM occurs. **/ |
129 |
/** They allow to control memory access. **/ |
130 |
/************************************ TO BE WRITTEN BY USER **/ |
131 |
void WrZ80(register word Addr,register byte Value); |
132 |
byte RdZ80(register word Addr); |
133 |
|
134 |
/** InZ80()/OutZ80() *****************************************/ |
135 |
/** Z80 emulation calls these functions to read/write from **/ |
136 |
/** I/O ports. There can be 65536 I/O ports, but only first **/ |
137 |
/** 256 are usually used. **/ |
138 |
/************************************ TO BE WRITTEN BY USER **/ |
139 |
void OutZ80(register word Port,register byte Value); |
140 |
byte InZ80(register word Port); |
141 |
|
142 |
/** PatchZ80() ***********************************************/ |
143 |
/** Z80 emulation calls this function when it encounters a **/ |
144 |
/** special patch command (ED FE) provided for user needs. **/ |
145 |
/** For example, it can be called to emulate BIOS calls, **/ |
146 |
/** such as disk and tape access. Replace it with an empty **/ |
147 |
/** macro for no patching. **/ |
148 |
/************************************ TO BE WRITTEN BY USER **/ |
149 |
void PatchZ80(register Z80 *R); |
150 |
|
151 |
/** DebugZ80() ***********************************************/ |
152 |
/** This function should exist if DEBUG is #defined. When **/ |
153 |
/** Trace!=0, it is called after each command executed by **/ |
154 |
/** the CPU, and given the Z80 registers. Emulation exits **/ |
155 |
/** if DebugZ80() returns 0. **/ |
156 |
/*************************************************************/ |
157 |
#ifdef DEBUG |
158 |
byte DebugZ80(register Z80 *R); |
159 |
#endif |
160 |
|
161 |
/** LoopZ80() ************************************************/ |
162 |
/** Z80 emulation calls this function periodically to check **/ |
163 |
/** if the system hardware requires any interrupts. This **/ |
164 |
/** function must return an address of the interrupt vector **/ |
165 |
/** (0x0038, 0x0066, etc.) or INT_NONE for no interrupt. **/ |
166 |
/** Return INT_QUIT to exit the emulation loop. **/ |
167 |
/************************************ TO BE WRITTEN BY USER **/ |
168 |
word LoopZ80(register Z80 *R); |
169 |
|
170 |
/** JumpZ80() ************************************************/ |
171 |
/** Z80 emulation calls this function when it executes a **/ |
172 |
/** JP, JR, CALL, RST, or RET. You can use JumpZ80() to **/ |
173 |
/** trap these opcodes and switch memory layout. **/ |
174 |
/************************************ TO BE WRITTEN BY USER **/ |
175 |
#ifndef JUMPZ80 |
176 |
#define JumpZ80(PC) |
177 |
#else |
178 |
void JumpZ80(word PC); |
179 |
#endif |
180 |
|
181 |
#endif /* Z80_H */ |