1 #ifndef HEADER__G65816CM
2 #define HEADER__G65816CM
3
4 #define g65816i_branching(A)
5 #define g65816i_jumping(A)
6
7
8 /* ======================================================================== */
9 /* ================================ INCLUDES ============================== */
10 /* ======================================================================== */
11 #include <stdio.h>
12 #include <limits.h>
13
14 #include <retro_inline.h>
15
16 #include "g65816.h"
17
18 /* ======================================================================== */
19 /* ================================ GENERAL =============================== */
20 /* ======================================================================== */
21
22 /* This should be set to the default size of your processor (min 16 bit) */
23 #undef uint
24 #define uint unsigned int
25
26 #undef uint8
27 #define uint8 unsigned char
28
29 #undef int8
30
31 /* Allow for architectures that don't have 8-bit sizes */
32 #if UCHAR_MAX == 0xff
33 #define int8 char
34 #define MAKE_INT_8(A) (int8)((A)&0xff)
35 #else
36 #define int8 int
MAKE_INT_8(int A)37 static INLINE int MAKE_INT_8(int A) {return (A & 0x80) ? A | ~0xff : A & 0xff;}
38 #endif /* UCHAR_MAX == 0xff */
39
40 #define MAKE_UINT_8(A) ((A)&0xff)
41 #define MAKE_UINT_16(A) ((A)&0xffff)
42 #define MAKE_UINT_24(A) ((A)&0xffffff)
43
44 /* Bits */
45 #define BIT_0 0x01
46 #define BIT_1 0x02
47 #define BIT_2 0x04
48 #define BIT_3 0x08
49 #define BIT_4 0x10
50 #define BIT_5 0x20
51 #define BIT_6 0x40
52 #define BIT_7 0x80
53
54
55 /* ======================================================================== */
56 /* ================================== CPU ================================= */
57 /* ======================================================================== */
58
59 /* CPU Structure */
60 typedef struct
61 {
62 uint a; /* Accumulator */
63 uint b; /* holds high byte of accumulator */
64 uint x; /* Index Register X */
65 uint y; /* Index Register Y */
66 uint s; /* Stack Pointer */
67 uint pc; /* Program Counter */
68 uint ppc; /* Previous Program Counter */
69 uint pb; /* Program Bank (shifted left 16) */
70 uint db; /* Data Bank (shifted left 16) */
71 uint d; /* Direct Register */
72 uint flag_e; /* Emulation Mode Flag */
73 uint flag_m; /* Memory/Accumulator Select Flag */
74 uint flag_x; /* Index Select Flag */
75 uint flag_n; /* Negative Flag */
76 uint flag_v; /* Overflow Flag */
77 uint flag_d; /* Decimal Mode Flag */
78 uint flag_i; /* Interrupt Mask Flag */
79 uint flag_z; /* Zero Flag (inverted) */
80 uint flag_c; /* Carry Flag */
81 uint line_irq; /* Status of the IRQ line */
82 uint line_nmi; /* Status of the NMI line */
83 uint ir; /* Instruction Register */
84 uint irq_delay; /* delay 1 instruction before checking irq */
85 int (*int_ack)(int); /* Interrupt Acknowledge */
86 uint stopped; /* Sets how the CPU is stopped */
87 void (**opcodes)(void);
88 uint (*get_reg)(int regnum);
89 void (*set_reg)(int regnum, uint val);
90 void (*set_line)(int line, int state);
91 int (*execute)(int cycles);
92 } g65816i_cpu_struct;
93
94 extern g65816i_cpu_struct g65816i_cpu;
95 extern int g65816_ICount;
96 extern uint g65816i_source;
97 extern uint g65816i_destination;
98
99 extern void (**g65816i_opcodes[])(void);
100 extern uint (*g65816i_get_reg[])(int regnum);
101 extern void (*g65816i_set_reg[])(int regnum, uint val);
102 extern void (*g65816i_set_line[])(int line, int state);
103 extern int (*g65816i_execute[])(int cycles);
104
105 #define REGISTER_A g65816i_cpu.a /* Accumulator */
106 #define REGISTER_B g65816i_cpu.b /* Accumulator hi byte */
107 #define REGISTER_X g65816i_cpu.x /* Index X Register */
108 #define REGISTER_Y g65816i_cpu.y /* Index Y Register */
109 #define REGISTER_S g65816i_cpu.s /* Stack Pointer */
110 #define REGISTER_PC g65816i_cpu.pc /* Program Counter */
111 #define REGISTER_PPC g65816i_cpu.ppc /* Previous Program Counter */
112 #define REGISTER_PB g65816i_cpu.pb /* Program Bank */
113 #define REGISTER_DB g65816i_cpu.db /* Data Bank */
114 #define REGISTER_D g65816i_cpu.d /* Direct Register */
115 #define FLAG_E g65816i_cpu.flag_e /* Emulation Mode Flag */
116 #define FLAG_M g65816i_cpu.flag_m /* Memory/Accumulator Select Flag */
117 #define FLAG_X g65816i_cpu.flag_x /* Index Select Flag */
118 #define FLAG_N g65816i_cpu.flag_n /* Negative Flag */
119 #define FLAG_V g65816i_cpu.flag_v /* Overflow Flag */
120 #define FLAG_D g65816i_cpu.flag_d /* Decimal Mode Flag */
121 #define FLAG_I g65816i_cpu.flag_i /* Interrupt Mask Flag */
122 #define FLAG_Z g65816i_cpu.flag_z /* Zero Flag (inverted) */
123 #define FLAG_C g65816i_cpu.flag_c /* Carry Flag */
124 #define LINE_IRQ g65816i_cpu.line_irq /* Status of the IRQ line */
125 #define LINE_NMI g65816i_cpu.line_nmi /* Status of the NMI line */
126 #define REGISTER_IR g65816i_cpu.ir /* Instruction Register */
127 #define INT_ACK g65816i_cpu.int_ack /* Interrupt Acknowledge function pointer */
128 #define CLOCKS g65816_ICount /* Clock cycles remaining */
129 #define IRQ_DELAY g65816i_cpu.irq_delay /* Delay 1 instruction before checking IRQ */
130 #define CPU_STOPPED g65816i_cpu.stopped /* Stopped status of the CPU */
131
132 #define FTABLE_OPCODES g65816i_cpu.opcodes
133 #define FTABLE_GET_REG g65816i_cpu.get_reg
134 #define FTABLE_SET_REG g65816i_cpu.set_reg
135 #define FTABLE_SET_LINE g65816i_cpu.set_line
136 #define FTABLE_EXECUTE g65816i_cpu.execute
137
138 #define SRC g65816i_source /* Source Operand */
139 #define DST g65816i_destination /* Destination Operand */
140
141 #define STOP_LEVEL_WAI 1
142 #define STOP_LEVEL_STOP 2
143
144 #define EXECUTION_MODE_M0X0 0
145 #define EXECUTION_MODE_M0X1 1
146 #define EXECUTION_MODE_M1X0 2
147 #define EXECUTION_MODE_M1X1 3
148 #define EXECUTION_MODE_E 4
149
g65816i_set_execution_mode(uint mode)150 static INLINE void g65816i_set_execution_mode(uint mode)
151 {
152 FTABLE_OPCODES = g65816i_opcodes[mode];
153 FTABLE_GET_REG = g65816i_get_reg[mode];
154 FTABLE_SET_REG = g65816i_set_reg[mode];
155 FTABLE_SET_LINE = g65816i_set_line[mode];
156 FTABLE_EXECUTE = g65816i_execute[mode];
157 }
158
159
160
161 #define VECTOR_RESET 0xfffc /* Reset */
162 #define VECTOR_IRQ_E 0xfffe /* Interrupt Request */
163 #define VECTOR_NMI_E 0xfffa /* Non-Maskable Interrupt */
164 #define VECTOR_ABORT_E 0xfff8 /* ABORT asserted */
165 #define VECTOR_BRK_E 0xfffe /* Break Instruction */
166 #define VECTOR_COP_E 0xfff4 /* Coprocessor instruction */
167
168 #define VECTOR_IRQ_N 0xffee /* Interrupt Request */
169 #define VECTOR_NMI_N 0xffea /* Non-Maskable Interrupt */
170 #define VECTOR_ABORT_N 0xffe8 /* ABORT asserted */
171 #define VECTOR_BRK_N 0xffe6 /* Break Instruction */
172 #define VECTOR_COP_N 0xffe4 /* Coprocessor instruction */
173
174
175 /* ======================================================================== */
176 /* ================================= CLOCK ================================ */
177 /* ======================================================================== */
178
179 #define CLK_OP 1
180 #define CLK_R8 1
181 #define CLK_R16 2
182 #define CLK_R24 3
183 #define CLK_W8 1
184 #define CLK_W16 2
185 #define CLK_W24 3
186 #define CLK_RMW8 3
187 #define CLK_RMW16 5
188
189 #define CLK_IMPLIED 1
190 #define CLK_IMPLIED 1
191 #define CLK_RELATIVE_8 1
192 #define CLK_RELATIVE_16 2
193 #define CLK_IMM 0
194 #define CLK_AI 4
195 #define CLK_AXI 4
196 #define CLK_A 2
197 #define CLK_AL 3
198 #define CLK_ALX 3
199 #define CLK_AX 2
200 #define CLK_AY 2
201 #define CLK_D 1
202 #define CLK_DI 3
203 #define CLK_DIY 3
204 #define CLK_DLI 4
205 #define CLK_DLIY 4
206 #define CLK_DX 2
207 #define CLK_DXI 4
208 #define CLK_DY 2
209 #define CLK_S 2
210 #define CLK_SIY 5
211
212 /* AX and AY addressing modes take 1 extra cycle when writing */
213 #define CLK_W_IMM 0
214 #define CLK_W_AI 4
215 #define CLK_W_AXI 4
216 #define CLK_W_A 2
217 #define CLK_W_AL 3
218 #define CLK_W_ALX 3
219 #define CLK_W_AX 3
220 #define CLK_W_AY 3
221 #define CLK_W_D 1
222 #define CLK_W_DI 3
223 #define CLK_W_DIY 3
224 #define CLK_W_DLI 4
225 #define CLK_W_DLIY 4
226 #define CLK_W_DX 2
227 #define CLK_W_DXI 4
228 #define CLK_W_DY 2
229 #define CLK_W_S 2
230 #define CLK_W_SIY 5
231
232 #define CLK(A) CLOCKS -= (A)
233 #define USE_ALL_CLKS() CLOCKS = 0
234
235
236 /* ======================================================================== */
237 /* ============================ STATUS REGISTER =========================== */
238 /* ======================================================================== */
239
240 /* Flag positions in Processor Status Register */
241 /* common */
242 #define FLAGPOS_N BIT_7 /* Negative */
243 #define FLAGPOS_V BIT_6 /* Overflow */
244 #define FLAGPOS_D BIT_3 /* Decimal Mode */
245 #define FLAGPOS_I BIT_2 /* Interrupt Mask */
246 #define FLAGPOS_Z BIT_1 /* Zero */
247 #define FLAGPOS_C BIT_0 /* Carry */
248 /* emulation */
249 #define FLAGPOS_R BIT_5 /* Reserved */
250 #define FLAGPOS_B BIT_4 /* BRK Instruction */
251 /* native */
252 #define FLAGPOS_M BIT_5 /* Mem/Reg Select */
253 #define FLAGPOS_X BIT_4 /* Index Select */
254
255 #define EFLAG_SET 1
256 #define EFLAG_CLEAR 0
257 #define MFLAG_SET FLAGPOS_M
258 #define MFLAG_CLEAR 0
259 #define XFLAG_SET FLAGPOS_X
260 #define XFLAG_CLEAR 0
261 #define NFLAG_SET 0x80
262 #define NFLAG_CLEAR 0
263 #define VFLAG_SET 0x80
264 #define VFLAG_CLEAR 0
265 #define DFLAG_SET FLAGPOS_D
266 #define DFLAG_CLEAR 0
267 #define IFLAG_SET FLAGPOS_I
268 #define IFLAG_CLEAR 0
269 #define BFLAG_SET FLAGPOS_B
270 #define BFLAG_CLEAR 0
271 #define ZFLAG_SET 0
272 #define ZFLAG_CLEAR 1
273 #define CFLAG_SET 0x100
274 #define CFLAG_CLEAR 0
275
276 /* Codition code tests */
277 #define COND_CC() (!(FLAG_C&0x100)) /* Carry Clear */
278 #define COND_CS() (FLAG_C&0x100) /* Carry Set */
279 #define COND_EQ() (!FLAG_Z) /* Equal */
280 #define COND_NE() FLAG_Z /* Not Equal */
281 #define COND_MI() (FLAG_N&0x80) /* Minus */
282 #define COND_PL() (!(FLAG_N&0x80)) /* Plus */
283 #define COND_VC() (!(FLAG_V&0x80)) /* Overflow Clear */
284 #define COND_VS() (FLAG_V&0x80) /* Overflow Set */
285
286 /* Set Overflow flag in math operations */
287 #define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
288 #define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
289 #define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
290 #define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
291
292 #define CFLAG_8(A) (A)
293 #define CFLAG_16(A) ((A)>>8)
294 #define NFLAG_8(A) (A)
295 #define NFLAG_16(A) ((A)>>8)
296
297 #define CFLAG_AS_1() ((FLAG_C>>8)&1)
298
299
300
301 /* ======================================================================== */
302 /* ================================== CPU ================================= */
303 /* ======================================================================== */
304 #endif /* HEADER__G65816CM */
305