fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 337 lines 12 kB view raw
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