-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpu.h
231 lines (167 loc) · 6.12 KB
/
cpu.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
#ifndef LIB65816_CPU_H
#define LIB65816_CPU_H
/*
* lib65816/cpu.h Release 1p1
* See LICENSE for more details.
*
* Code originally from XGS: Apple IIGS Emulator (gscpu.h)
*
* Originally written and Copyright (C)1996 by Joshua M. Thompson
* Copyright (C) 2006 by Samuel A. Falvo II
*
* Modified for greater portability and virtual hardware independence.
*/
#include "816lib/lib65816/config.h"
/* Type definitions for convenience. These are not intended to be used
* outside the scope of lib65816, since it might conflict with other
* libraries type definitions.
*/
typedef unsigned char byte;
typedef signed char sbyte;
#if SIZEOF_LONG == 4
typedef unsigned long word32;
typedef signed long sword32;
#elif SIZEOF_INT == 4
typedef unsigned int word32;
typedef signed int sword32;
#endif
#if SIZEOF_SHORT == 2
typedef unsigned short word16;
typedef signed short sword16;
#elif SIZEOF_INT == 2
typedef unsigned int word16;
typedef signed int sword16;
#endif
typedef signed char offset_s; /* short offset */
typedef signed short offset_l; /* long offset */
/*
* Union definition of a 16-bit value that can also be
* accessed as its component 8-bit values. Useful for
* registers, which change sized based on teh settings
* the M and X program status register bits.
*/
typedef union {
#ifdef WORDS_BIGENDIAN
struct { byte H,L; } B;
#else
struct { byte L,H; } B;
#endif
word16 W;
} dualw;
/* Same as above but for addresses. */
typedef union {
#ifdef WORDS_BIGENDIAN
struct { byte Z,B,H,L; } B;
struct { word16 H,L; } W;
#else
struct { byte L,H,B,Z; } B;
struct { word16 L,H; } W;
#endif
word32 A;
} duala;
/* Definitions of the 65816 registers, in case you want
* to access these from your own routines (such as from
* a WDM opcode handler routine.
*
* ATTENTION: DO NOT DEPEND ON THESE -- THESE WILL EVENTUALLY BE REPLACED
* WITH A STRUCTURE THAT MAINTAINS ALL CPU STATE.
*/
extern dualw A; /* Accumulator */
extern dualw D; /* Direct Page Register */
extern byte P; /* Processor Status Register */
extern int E; /* Emulation Mode Flag */
extern dualw S; /* Stack Pointer */
extern dualw X; /* X Index Register */
extern dualw Y; /* Y Index Register */
extern byte DB; /* Data Bank Register */
#ifndef CPU_DISPATCH
typedef union { /* Program Counter */
#ifdef WORDS_BIGENDIAN
struct { byte Z,PB,H,L; } B;
struct { word16 Z,PC; } W;
#else
struct { byte L,H,PB,Z; } B;
struct { word16 PC,Z; } W;
#endif
word32 A;
} PC_union;
extern PC_union PC;
#endif
/* Current cycle count */
#if defined ( __sparc__ ) && defined ( __GNUC__ )
register word32 cpu_cycle_count asm ("g5");
#else
extern word32 cpu_cycle_count;
#endif
/* These are the core memory access macros used in the 65816 emulator.
* Set these to point to routines which handle your emulated machine's
* memory access (generally these routines will check for access to
* memory-mapped I/O and things of that nature.)
*
* The SYNC pin is useful to trap OS calls, whereas the VP pin is
* needed to emulate hardware which modifies the vector addresses.
*/
#define EMUL_PIN_SYNC 1 // much more work to provide VPD and VPA
#define EMUL_PIN_VP 2
#define M_READ(a) MEM_readMem(a, cpu_cycle_count, 0)
#define M_READ_OPCODE(a) MEM_readMem(a, cpu_cycle_count, EMUL_PIN_SYNC)
#define M_READ_VECTOR(a) MEM_readMem(a, cpu_cycle_count, EMUL_PIN_VP)
#define M_WRITE(a,v) MEM_writeMem((a),(v), cpu_cycle_count)
/* Set this macro to your emulator's "update" routine. Your update
* routine would probably do things like update hardware sprites,
* and check for user keypresses. CPU_run() calls this routine
* periodically to make sure the rest of your emulator gets time
* to run.
*
* v is the number of CPU clock cycles that have elapsed since the last
* call.
*/
#define E_UPDATE(v) EMUL_hardwareUpdate(v)
/* Set this macro to your emulator's routine for handling the WDM
* pseudo-opcode. Useful for trapping certain emulated machine
* functions and emulating them in fast C code.
*
* v is the operand byte immediately following the WDM opcode.
*/
#define E_WDM(v) EMUL_handleWDM( (v), cpu_cycle_count )
void CPUEvent_initialize( void );
/* Set the 65816 emulator's update period (the number of cycles
* elapsed between calls to the E_UPDATE routine.)
*/
void CPU_setUpdatePeriod(word32 period);
/* Set the 65816 emulator's trace mode to off (0) or on (nonzero) */
void CPU_setTrace(int mode);
/* Send a reset to the 65816 emulator. You should do this at */
/* startup before you call CPU_run(). */
void CPU_reset(void);
/* Exit the cpu run loop */
void CPU_quit(void);
/* Send an abort to the 65816 emulator. */
void CPU_abort(void);
/* Send a non-maskable interrupt to the 65816 emulator */
void CPU_nmi(void);
/* Send a standard (maskable) interrupt to the 65816 emulator. Up to 32
* IRQ sources are supported. */
void CPU_addIRQ( word32 mask );
/* Clear a previously sent interrupt (if one is still pending) */
void CPU_clearIRQ( word32 mask );
/* This routine never returns; it sits in a loop processing opcodes */
/* until the emulator exits. Periodic calls to the emulator update */
/* macro are made to allow the rest of the emulator to function. */
void CPU_run(void);
/* Internal routine called when the mode bits (e/m/x) change */
void CPU_modeSwitch(void);
/* Internal routine to print the next instruction in trace mode */
void CPU_debug(void);
/* These are used by the various macros above, so make sure that we
* declare them for type safety purposes! Thanks to fabys for these on
* the 6502.org forum.
*
* Thanks to BigEd on 6502.org for implementing support for memory access
* modes -- see EMUL_* macros above, near MEM_READ_*, et. al.
*/
void EMUL_handleWDM(byte opcode, word32 timestamp);
void EMUL_hardwareUpdate(word32 timestamp);
byte MEM_readMem(word32 address, word32 timestamp, word32 emulFlags);
void MEM_writeMem(word32 address, byte b, word32 timestamp);
#endif /* _CPU_H */