fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/e6502/e6502.h *
7 * Created: 2004-05-02 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2022 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#ifndef PCE_E6502_H
24#define PCE_E6502_H 1
25
26
27#include <stdio.h>
28
29
30#define E6502_FLAG_IOPORT 1
31#define E6502_FLAG_UNDEF 2
32
33
34/* CPU flags */
35#define E6502_FLG_N 0x80
36#define E6502_FLG_V 0x40
37#define E6502_FLG_R 0x20
38#define E6502_FLG_B 0x10
39#define E6502_FLG_D 0x08
40#define E6502_FLG_I 0x04
41#define E6502_FLG_Z 0x02
42#define E6502_FLG_C 0x01
43
44#define E6502_MAP_BITS 8
45#define E6502_MAP_PAGES (1 << (16 - E6502_MAP_BITS))
46#define E6502_MAP_SIZE (1 << E6502_MAP_BITS)
47#define E6502_MAP_MASK ((1 << E6502_MAP_BITS) - 1)
48
49
50struct e6502_t;
51
52
53typedef void (*e6502_opcode_f) (struct e6502_t *c);
54
55
56typedef struct e6502_t {
57 unsigned flags;
58
59 unsigned short pc;
60 unsigned char a;
61 unsigned char x;
62 unsigned char y;
63 unsigned char s;
64 unsigned char p;
65
66 char check_irq;
67
68 unsigned short lpc;
69
70 unsigned short ea;
71 char ea_page;
72
73 unsigned char rst_val;
74 unsigned char irq_val;
75 unsigned char nmi_val;
76 unsigned char nmi_pnd;
77
78 void *mem_rd_ext;
79 void *mem_wr_ext;
80
81 unsigned char (*get_uint8) (void *ext, unsigned long addr);
82 void (*set_uint8) (void *ext, unsigned long addr, unsigned char val);
83
84 void *set_ioport_ext;
85 void (*set_ioport) (void *ext, unsigned char val);
86
87 unsigned char *mem_map_rd[E6502_MAP_PAGES];
88 unsigned char *mem_map_wr[E6502_MAP_PAGES];
89
90 void *hook_ext;
91 int (*hook_all) (void *ext, unsigned char op);
92 int (*hook_undef) (void *ext, unsigned char op);
93 int (*hook_brk) (void *ext, unsigned char op);
94
95 unsigned char ioport[3];
96
97 unsigned char inst[4];
98
99 e6502_opcode_f op[256];
100
101 unsigned long delay;
102 unsigned long clkcnt;
103 unsigned long inscnt;
104} e6502_t;
105
106
107#define e6502_get_pc(c) ((c)->pc)
108#define e6502_get_lpc(c) ((c)->lpc)
109#define e6502_get_a(c) ((c)->a)
110#define e6502_get_x(c) ((c)->x)
111#define e6502_get_y(c) ((c)->y)
112#define e6502_get_p(c) ((c)->p)
113#define e6502_get_s(c) ((c)->s)
114
115#define e6502_set_pc(c, v) do { (c)->pc = (v) & 0xffff; } while (0)
116#define e6502_set_lpc(c, v) do { (c)->lpc = (v) & 0xffff; } while (0)
117#define e6502_set_a(c, v) do { (c)->a = (v) & 0xff; } while (0)
118#define e6502_set_x(c, v) do { (c)->x = (v) & 0xff; } while (0)
119#define e6502_set_y(c, v) do { (c)->y = (v) & 0xff; } while (0)
120#define e6502_set_p(c, v) do { (c)->p = (v) & 0xff; } while (0)
121#define e6502_set_s(c, v) do { (c)->s = (v) & 0xff; } while (0)
122
123#define e6502_get_nf(c) (((c)->p & E6502_FLG_N) != 0)
124#define e6502_get_vf(c) (((c)->p & E6502_FLG_V) != 0)
125#define e6502_get_rf(c) (((c)->p & E6502_FLG_R) != 0)
126#define e6502_get_bf(c) (((c)->p & E6502_FLG_B) != 0)
127#define e6502_get_df(c) (((c)->p & E6502_FLG_D) != 0)
128#define e6502_get_if(c) (((c)->p & E6502_FLG_I) != 0)
129#define e6502_get_zf(c) (((c)->p & E6502_FLG_Z) != 0)
130#define e6502_get_cf(c) (((c)->p & E6502_FLG_C) != 0)
131
132#define e6502_set_flag(c, f, v) \
133 do { if (v) (c)->p |= (f); else (c)->p &= ~(f); } while (0)
134
135#define e6502_set_nf(c, v) e6502_set_flag (c, E6502_FLG_N, v)
136#define e6502_set_vf(c, v) e6502_set_flag (c, E6502_FLG_V, v)
137#define e6502_set_rf(c, v) e6502_set_flag (c, E6502_FLG_R, v)
138#define e6502_set_bf(c, v) e6502_set_flag (c, E6502_FLG_B, v)
139#define e6502_set_df(c, v) e6502_set_flag (c, E6502_FLG_D, v)
140#define e6502_set_if(c, v) e6502_set_flag (c, E6502_FLG_I, v)
141#define e6502_set_zf(c, v) e6502_set_flag (c, E6502_FLG_Z, v)
142#define e6502_set_cf(c, v) e6502_set_flag (c, E6502_FLG_C, v)
143
144
145unsigned char e6502_get_ioport_8 (e6502_t *c, unsigned long addr);
146void e6502_set_ioport_8 (e6502_t *c, unsigned long addr, unsigned char val);
147
148
149static inline
150unsigned char e6502_get_mem8 (e6502_t *c, unsigned short addr)
151{
152 const unsigned char *p;
153
154 if ((addr < 2) && (c->flags & E6502_FLAG_IOPORT)) {
155 return (e6502_get_ioport_8 (c, addr));
156 }
157
158 if ((p = c->mem_map_rd[(addr & 0xffff) >> E6502_MAP_BITS]) != NULL) {
159 return (p[addr & E6502_MAP_MASK]);
160 }
161
162 return (c->get_uint8 (c->mem_rd_ext, addr));
163}
164
165static inline
166void e6502_set_mem8 (e6502_t *c, unsigned short addr, unsigned char val)
167{
168 unsigned char *p;
169
170 if ((addr < 2) && (c->flags & E6502_FLAG_IOPORT)) {
171 e6502_set_ioport_8 (c, addr, val);
172 return;
173 }
174
175 if ((p = c->mem_map_wr[(addr & 0xffff) >> E6502_MAP_BITS]) != NULL) {
176 p[addr & E6502_MAP_MASK] = val;
177 }
178 else {
179 c->set_uint8 (c->mem_wr_ext, addr, val);
180 }
181}
182
183#define e6502_get_mem16(c, addr) ( \
184 (e6502_get_mem8 ((c), (addr) & 0xffff) & 0xff) | \
185 ((e6502_get_mem8 ((c), ((addr) + 1) & 0xffff) & 0xff) << 8) )
186
187#define e6502_set_mem16(c, addr, v) do { \
188 e6502_set_mem8 ((c), (addr) & 0xffff, (v) & 0xff); \
189 e6502_set_mem8 ((c), ((addr) + 1) & 0xffff, ((v) >> 8) & 0xff); \
190 } while (0)
191
192
193/*****************************************************************************
194 * @short Initialize a 6502 context
195 *****************************************************************************/
196void e6502_init (e6502_t *c);
197
198/*****************************************************************************
199 * @short Create and initialize a new 6502 context
200 *****************************************************************************/
201e6502_t *e6502_new (void);
202
203/*****************************************************************************
204 * @short Free the resources used by a 6502 context
205 *****************************************************************************/
206void e6502_free (e6502_t *c);
207
208/*****************************************************************************
209 * @short Delete a 6502 context
210 *****************************************************************************/
211void e6502_del (e6502_t *c);
212
213
214void e6502_set_mem_map_rd (e6502_t *c, unsigned addr1, unsigned addr2, unsigned char *p);
215void e6502_set_mem_map_wr (e6502_t *c, unsigned addr1, unsigned addr2, unsigned char *p);
216
217/*****************************************************************************
218 * @short Get the CPU flags
219 *****************************************************************************/
220unsigned e6502_get_flags (e6502_t *c);
221
222/*****************************************************************************
223 * @short Set the CPU flags
224 *****************************************************************************/
225void e6502_set_flags (e6502_t *c, unsigned flags);
226
227/*****************************************************************************
228 * @short Enable or disable the 6510 I/O port
229 *****************************************************************************/
230void e6502_set_ioport (e6502_t *c, int enable);
231
232/*****************************************************************************
233 * @short Enable or disable undefined instructions
234 *****************************************************************************/
235void e6502_set_undef (e6502_t *c, int enable);
236
237void e6502_set_mem_read_fct (e6502_t *c, void *ext, void *get8);
238void e6502_set_mem_write_fct (e6502_t *c, void *ext, void *set8);
239void e6502_set_mem_f (e6502_t *c, void *mem, void *get8, void *set8);
240
241void e6502_set_hook_all_fct (e6502_t *c, void *ext, void *fct);
242void e6502_set_hook_undef_fct (e6502_t *c, void *ext, void *fct);
243void e6502_set_hook_brk_fct (e6502_t *c, void *ext, void *fct);
244
245/*****************************************************************************
246 * @short Set the I/O port function
247 *****************************************************************************/
248void e6502_set_ioport_fct (e6502_t *c, void *ext, void *fct);
249
250/*****************************************************************************
251 * @short Set the I/O port input
252 *****************************************************************************/
253void e6502_set_ioport_inp (e6502_t *c, unsigned char val);
254void e6502_set_ioport_ddr (e6502_t *c, unsigned char val);
255
256
257int e6502_get_reg (e6502_t *c, const char *reg, unsigned long *val);
258int e6502_set_reg (e6502_t *c, const char *reg, unsigned long val);
259
260
261/*****************************************************************************
262 * @short Get the number of executed clock cycles
263 *****************************************************************************/
264unsigned long e6502_get_clock (e6502_t *c);
265
266/*****************************************************************************
267 * @short Get the number of executed instructions
268 *****************************************************************************/
269unsigned long e6502_get_opcnt (e6502_t *c);
270
271/*****************************************************************************
272 * @short Get the current delay
273 *****************************************************************************/
274unsigned long e6502_get_delay (e6502_t *c);
275
276
277/*****************************************************************************
278 * @short Set the 6502 RST line
279 *****************************************************************************/
280void e6502_set_reset (e6502_t *c, unsigned char val);
281
282/*****************************************************************************
283 * @short Set the 6502 IRQ line
284 *****************************************************************************/
285void e6502_set_irq (e6502_t *c, unsigned char val);
286
287/*****************************************************************************
288 * @short Set the 6502 NMI line
289 *****************************************************************************/
290void e6502_set_nmi (e6502_t *c, unsigned char val);
291
292
293/*****************************************************************************
294 * @short Reset the 6502
295 *****************************************************************************/
296void e6502_reset (e6502_t *c);
297
298/*****************************************************************************
299 * @short Execute one instruction
300 *****************************************************************************/
301void e6502_execute (e6502_t *c);
302
303/*****************************************************************************
304 * @short Clock the 6502
305 * @param c The 6502 context
306 * @param n The number of clock cycles
307 *****************************************************************************/
308void e6502_clock (e6502_t *c, unsigned n);
309
310
311
312#define E6502_OPF_BRA 0x0001
313#define E6502_OPF_JSR 0x0002
314#define E6502_OPF_RTI 0x0004
315#define E6502_OPF_RTS 0x0008
316#define E6502_OPF_UND 0x0010
317
318typedef struct {
319 unsigned flags;
320
321 unsigned short pc;
322 unsigned dat_n;
323 unsigned char dat[16];
324
325 char op[64];
326
327 unsigned arg_n;
328 char arg1[64];
329} e6502_disasm_t;
330
331
332void e6502_disasm (e6502_disasm_t *op, unsigned char *src, unsigned short pc);
333void e6502_disasm_mem (e6502_t *c, e6502_disasm_t *op, unsigned short pc);
334void e6502_disasm_cur (e6502_t *c, e6502_disasm_t *op);
335
336
337#endif