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