-
Notifications
You must be signed in to change notification settings - Fork 17
/
z80.h
272 lines (236 loc) · 8.22 KB
/
z80.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/*
* Copyright (C) 1992 Clarendon Hill Software.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute this software, provided this copyright notice is retained.
*
* This software is provided "as is" without any expressed or implied
* warranty. If this software brings on any sort of damage -- physical,
* monetary, emotional, or brain -- too bad. You've got no one to blame
* but yourself.
*
* The software may be modified for your own purposes, but modified versions
* must retain this notice.
*/
/*
* Portions copyright (c) 1996-2008, Timothy P. Mann
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _Z80_H
#define _Z80_H
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif
typedef unsigned int Uint; /* 4 bytes */
typedef unsigned short Ushort; /* 2 bytes */
typedef unsigned char Uchar; /* 1 byte */
#if __WORDSIZE == 32
typedef unsigned long long tstate_t;
#define TSTATE_T_MID (((unsigned long long) -1LL)/2ULL)
#define TSTATE_T_LEN "llu"
#else
typedef unsigned long tstate_t;
#define TSTATE_T_MID (((unsigned long) -1L)/2UL)
#define TSTATE_T_LEN "lu"
#endif
struct twobyte
{
#ifdef big_endian
Uchar high, low;
#else
Uchar low, high;
#endif
};
struct fourbyte
{
#ifdef big_endian
Uchar byte3, byte2, byte1, byte0;
#else
Uchar byte0, byte1, byte2, byte3;
#endif
};
/* for implementing registers which can be seen as bytes or words: */
typedef union
{
struct twobyte byte;
Ushort word;
} wordregister;
struct z80_state_struct
{
wordregister af;
wordregister bc;
wordregister de;
wordregister hl;
wordregister ix;
wordregister iy;
wordregister sp;
wordregister pc;
wordregister af_prime;
wordregister bc_prime;
wordregister de_prime;
wordregister hl_prime;
Uchar i; /* interrupt-page address register */
Uchar r; /* memory-refresh register, bits 0-6 */
Uchar r7; /* memory-refresh register, bit 7 */
Uchar iff1, iff2;
Uchar interrupt_mode;
/* To signal a maskable interrupt, set irq TRUE. The CPU does not
* turn off irq; the external device must turn it off when
* appropriately tickled by some IO port or memory address that it
* decodes. INT is level triggered, so Z-80 code must tickle the
* device before reenabling interrupts.
*
* There is no support as yet for fetching an interrupt vector or
* RST instruction from the interrupting device, as this gets
* rather complex when there can be more than one device with an
* interrupt pending. So you'd better use interrupt_mode 1 only
* (which is what the TRS-80 does).
*/
int irq;
/* To signal a nonmaskable interrupt, set nmi to TRUE. The CPU
* does not turn off nmi; the external device must turn it off
* when tickled (or after a timeout). NMI is edge triggered, so
* it has to be turned off and back on again before it can cause
* another interrupt. nmi_seen remembers that an edge has been seen,
* so turn off both nmi and nmi_seen when the interrupt is acknowledged.
*/
int nmi, nmi_seen;
/* Speed control. 0 = full speed */
int delay;
int keydelay; /* extra delay while any keys are pressed */
/* Cyclic T-state counter */
tstate_t t_count;
/* Clock in MHz = T-states per microsecond */
float clockMHz;
/* Simple event scheduler. If nonzero, when t_count passes sched,
* trs_do_event() is called and sched is set to zero. */
tstate_t sched;
};
#define Z80_ADDRESS_LIMIT (1 << 16)
/*
* Register accessors:
*/
#define REG_A (z80_state.af.byte.high)
#define REG_F (z80_state.af.byte.low)
#define REG_B (z80_state.bc.byte.high)
#define REG_C (z80_state.bc.byte.low)
#define REG_D (z80_state.de.byte.high)
#define REG_E (z80_state.de.byte.low)
#define REG_H (z80_state.hl.byte.high)
#define REG_L (z80_state.hl.byte.low)
#define REG_IX_HIGH (z80_state.ix.byte.high)
#define REG_IX_LOW (z80_state.ix.byte.low)
#define REG_IY_HIGH (z80_state.iy.byte.high)
#define REG_IY_LOW (z80_state.iy.byte.low)
#define REG_SP (z80_state.sp.word)
#define REG_PC (z80_state.pc.word)
#define REG_AF (z80_state.af.word)
#define REG_BC (z80_state.bc.word)
#define REG_DE (z80_state.de.word)
#define REG_HL (z80_state.hl.word)
#define REG_AF_PRIME (z80_state.af_prime.word)
#define REG_BC_PRIME (z80_state.bc_prime.word)
#define REG_DE_PRIME (z80_state.de_prime.word)
#define REG_HL_PRIME (z80_state.hl_prime.word)
#define REG_IX (z80_state.ix.word)
#define REG_IY (z80_state.iy.word)
#define REG_I (z80_state.i)
#define REG_R (z80_state.r)
#define REG_R7 (z80_state.r7)
#define HIGH(p) (((struct twobyte *)(p))->high)
#define LOW(p) (((struct twobyte *)(p))->low)
#define T_COUNT(n) (z80_state.t_count += (n))
/*
* Flag accessors:
*
* Flags are:
*
* 7 6 5 4 3 2 1 0
* S Z - H - P/V N C
*
* C Carry
* N Subtract
* P/V Parity/Overflow
* H Half-carry
* Z Zero
* S Sign
*/
#define CARRY_MASK (0x1)
#define SUBTRACT_MASK (0x2)
#define PARITY_MASK (0x4)
#define OVERFLOW_MASK (0x4)
#define UNDOC3_MASK (0x8)
#define HALF_CARRY_MASK (0x10)
#define UNDOC5_MASK (0x20)
#define ZERO_MASK (0x40)
#define SIGN_MASK (0x80)
#define ALL_FLAGS_MASK (CARRY_MASK | SUBTRACT_MASK | OVERFLOW_MASK | \
HALF_CARRY_MASK | ZERO_MASK | SIGN_MASK)
#define SET_SIGN() (REG_F |= SIGN_MASK)
#define CLEAR_SIGN() (REG_F &= (~SIGN_MASK))
#define SET_ZERO() (REG_F |= ZERO_MASK)
#define CLEAR_ZERO() (REG_F &= (~ZERO_MASK))
#define SET_HALF_CARRY() (REG_F |= HALF_CARRY_MASK)
#define CLEAR_HALF_CARRY() (REG_F &= (~HALF_CARRY_MASK))
#define SET_OVERFLOW() (REG_F |= OVERFLOW_MASK)
#define CLEAR_OVERFLOW() (REG_F &= (~OVERFLOW_MASK))
#define SET_PARITY() (REG_F |= PARITY_MASK)
#define CLEAR_PARITY() (REG_F &= (~PARITY_MASK))
#define SET_SUBTRACT() (REG_F |= SUBTRACT_MASK)
#define CLEAR_SUBTRACT() (REG_F &= (~SUBTRACT_MASK))
#define SET_CARRY() (REG_F |= CARRY_MASK)
#define CLEAR_CARRY() (REG_F &= (~CARRY_MASK))
#define SIGN_FLAG (REG_F & SIGN_MASK)
#define ZERO_FLAG (REG_F & ZERO_MASK)
#define HALF_CARRY_FLAG (REG_F & HALF_CARRY_MASK)
#define OVERFLOW_FLAG (REG_F & OVERFLOW_MASK)
#define PARITY_FLAG (REG_F & PARITY_MASK)
#define SUBTRACT_FLAG (REG_F & SUBTRACT_MASK)
#define CARRY_FLAG (REG_F & CARRY_MASK)
extern struct z80_state_struct z80_state;
extern void z80_reset(void);
extern int z80_run(int continuous);
extern void mem_init(void);
extern int mem_read(int address);
extern void mem_write(int address, int value);
extern void mem_write_rom(int address, int value);
extern int mem_read_word(int address);
extern void mem_write_word(int address, int value);
Uchar *mem_pointer(int address, int writing);
extern int mem_block_transfer(Ushort dest, Ushort source, int direction,
Ushort count);
extern int load_hex(); /* returns highest address loaded + 1 */
extern void debug(const char *fmt, ...);
extern void error(const char *fmt, ...);
extern void warning(const char *fmt, ...);
extern void fatal(const char *fmt, ...);
extern void z80_out(int port, int value);
extern int z80_in(int port);
extern int disassemble(unsigned short pc);
extern void debug_init(void);
extern void debug_shell(void);
#endif