1 // license:BSD-3-Clause 2 // copyright-holders:Bryan McPhail 3 /***************************************************************************** 4 5 h6280.h Portable Hu6280 emulator interface 6 7 Copyright Bryan McPhail, mish@tendril.co.uk 8 9 This source code is based (with permission!) on the 6502 emulator by 10 Juergen Buchmueller. It is released as part of the Mame emulator project. 11 Let me know if you intend to use this code in any other project. 12 13 ******************************************************************************/ 14 15 #ifndef MAME_CPU_H6280_H6280_H 16 #define MAME_CPU_H6280_H6280_H 17 18 #pragma once 19 20 #include "sound/c6280.h" 21 22 #define H6280_LAZY_FLAGS 0 23 24 //************************************************************************** 25 // TYPE DEFINITIONS 26 //************************************************************************** 27 28 // ======================> h6280_device 29 30 // Used by core CPU interface 31 class h6280_device : public cpu_device, public device_mixer_interface 32 { 33 public: 34 // construction/destruction 35 h6280_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 36 37 // public interfaces 38 void set_irq_line(int irqline, int state); 39 40 // configuration port_in_cb()41 auto port_in_cb() { return m_port_in_cb.bind(); } // K0-7 at Pinout port_out_cb()42 auto port_out_cb() { return m_port_out_cb.bind(); } // O0-7 at Pinout 43 44 // hack to fix music speed in some Data East games (core bug, external strapping, DE 45 customization or ???) set_timer_scale(int scale)45 void set_timer_scale(int scale) { m_timer_scale = scale; } 46 47 /* functions for use by the PSG and joypad port only! */ 48 uint8_t io_get_buffer(); 49 void io_set_buffer(uint8_t); 50 51 protected: 52 // register enumeration 53 enum 54 { 55 H6280_PC = 1, 56 H6280_S, 57 H6280_P, 58 H6280_A, 59 H6280_X, 60 H6280_Y, 61 H6280_IRQ_MASK, 62 H6280_TIMER_STATE, 63 H6280_NMI_STATE, 64 H6280_IRQ1_STATE, 65 H6280_IRQ2_STATE, 66 H6280_IRQT_STATE, 67 H6280_MPR0, 68 H6280_MPR1, 69 H6280_MPR2, 70 H6280_MPR3, 71 H6280_MPR4, 72 H6280_MPR5, 73 H6280_MPR6, 74 H6280_MPR7 75 }; 76 77 // device-level overrides 78 virtual void device_add_mconfig(machine_config &config) override; 79 virtual void device_start() override; 80 virtual void device_reset() override; 81 virtual void device_stop() override; 82 83 // device_execute_interface overrides 84 virtual uint32_t execute_min_cycles() const noexcept override; 85 virtual uint32_t execute_max_cycles() const noexcept override; 86 virtual uint32_t execute_input_lines() const noexcept override; 87 virtual bool execute_input_edge_triggered(int inputnum) const noexcept override; 88 virtual void execute_run() override; 89 virtual void execute_set_input(int inputnum, int state) override; 90 91 // device_memory_interface overrides 92 virtual space_config_vector memory_space_config() const override; 93 virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; 94 95 // device_disasm_interface overrides 96 virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; 97 98 // device_state_interface overrides 99 virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; 100 101 // opcode accessors 102 uint8_t program_read8(offs_t addr); 103 void program_write8(offs_t addr, uint8_t data); 104 uint8_t program_read8z(offs_t addr); 105 void program_write8z(offs_t addr, uint8_t data); 106 uint16_t program_read16(offs_t addr); 107 uint16_t program_read16z(offs_t addr); 108 void push(uint8_t value); 109 void pull(uint8_t &value); 110 uint8_t read_opcode(); 111 uint8_t read_opcode_arg(); 112 113 #undef PROTOTYPES 114 #define PROTOTYPES(prefix) \ 115 void prefix##_00(); void prefix##_01(); void prefix##_02(); void prefix##_03(); \ 116 void prefix##_04(); void prefix##_05(); void prefix##_06(); void prefix##_07(); \ 117 void prefix##_08(); void prefix##_09(); void prefix##_0a(); void prefix##_0b(); \ 118 void prefix##_0c(); void prefix##_0d(); void prefix##_0e(); void prefix##_0f(); \ 119 void prefix##_10(); void prefix##_11(); void prefix##_12(); void prefix##_13(); \ 120 void prefix##_14(); void prefix##_15(); void prefix##_16(); void prefix##_17(); \ 121 void prefix##_18(); void prefix##_19(); void prefix##_1a(); void prefix##_1b(); \ 122 void prefix##_1c(); void prefix##_1d(); void prefix##_1e(); void prefix##_1f(); \ 123 void prefix##_20(); void prefix##_21(); void prefix##_22(); void prefix##_23(); \ 124 void prefix##_24(); void prefix##_25(); void prefix##_26(); void prefix##_27(); \ 125 void prefix##_28(); void prefix##_29(); void prefix##_2a(); void prefix##_2b(); \ 126 void prefix##_2c(); void prefix##_2d(); void prefix##_2e(); void prefix##_2f(); \ 127 void prefix##_30(); void prefix##_31(); void prefix##_32(); void prefix##_33(); \ 128 void prefix##_34(); void prefix##_35(); void prefix##_36(); void prefix##_37(); \ 129 void prefix##_38(); void prefix##_39(); void prefix##_3a(); void prefix##_3b(); \ 130 void prefix##_3c(); void prefix##_3d(); void prefix##_3e(); void prefix##_3f(); \ 131 void prefix##_40(); void prefix##_41(); void prefix##_42(); void prefix##_43(); \ 132 void prefix##_44(); void prefix##_45(); void prefix##_46(); void prefix##_47(); \ 133 void prefix##_48(); void prefix##_49(); void prefix##_4a(); void prefix##_4b(); \ 134 void prefix##_4c(); void prefix##_4d(); void prefix##_4e(); void prefix##_4f(); \ 135 void prefix##_50(); void prefix##_51(); void prefix##_52(); void prefix##_53(); \ 136 void prefix##_54(); void prefix##_55(); void prefix##_56(); void prefix##_57(); \ 137 void prefix##_58(); void prefix##_59(); void prefix##_5a(); void prefix##_5b(); \ 138 void prefix##_5c(); void prefix##_5d(); void prefix##_5e(); void prefix##_5f(); \ 139 void prefix##_60(); void prefix##_61(); void prefix##_62(); void prefix##_63(); \ 140 void prefix##_64(); void prefix##_65(); void prefix##_66(); void prefix##_67(); \ 141 void prefix##_68(); void prefix##_69(); void prefix##_6a(); void prefix##_6b(); \ 142 void prefix##_6c(); void prefix##_6d(); void prefix##_6e(); void prefix##_6f(); \ 143 void prefix##_70(); void prefix##_71(); void prefix##_72(); void prefix##_73(); \ 144 void prefix##_74(); void prefix##_75(); void prefix##_76(); void prefix##_77(); \ 145 void prefix##_78(); void prefix##_79(); void prefix##_7a(); void prefix##_7b(); \ 146 void prefix##_7c(); void prefix##_7d(); void prefix##_7e(); void prefix##_7f(); \ 147 void prefix##_80(); void prefix##_81(); void prefix##_82(); void prefix##_83(); \ 148 void prefix##_84(); void prefix##_85(); void prefix##_86(); void prefix##_87(); \ 149 void prefix##_88(); void prefix##_89(); void prefix##_8a(); void prefix##_8b(); \ 150 void prefix##_8c(); void prefix##_8d(); void prefix##_8e(); void prefix##_8f(); \ 151 void prefix##_90(); void prefix##_91(); void prefix##_92(); void prefix##_93(); \ 152 void prefix##_94(); void prefix##_95(); void prefix##_96(); void prefix##_97(); \ 153 void prefix##_98(); void prefix##_99(); void prefix##_9a(); void prefix##_9b(); \ 154 void prefix##_9c(); void prefix##_9d(); void prefix##_9e(); void prefix##_9f(); \ 155 void prefix##_a0(); void prefix##_a1(); void prefix##_a2(); void prefix##_a3(); \ 156 void prefix##_a4(); void prefix##_a5(); void prefix##_a6(); void prefix##_a7(); \ 157 void prefix##_a8(); void prefix##_a9(); void prefix##_aa(); void prefix##_ab(); \ 158 void prefix##_ac(); void prefix##_ad(); void prefix##_ae(); void prefix##_af(); \ 159 void prefix##_b0(); void prefix##_b1(); void prefix##_b2(); void prefix##_b3(); \ 160 void prefix##_b4(); void prefix##_b5(); void prefix##_b6(); void prefix##_b7(); \ 161 void prefix##_b8(); void prefix##_b9(); void prefix##_ba(); void prefix##_bb(); \ 162 void prefix##_bc(); void prefix##_bd(); void prefix##_be(); void prefix##_bf(); \ 163 void prefix##_c0(); void prefix##_c1(); void prefix##_c2(); void prefix##_c3(); \ 164 void prefix##_c4(); void prefix##_c5(); void prefix##_c6(); void prefix##_c7(); \ 165 void prefix##_c8(); void prefix##_c9(); void prefix##_ca(); void prefix##_cb(); \ 166 void prefix##_cc(); void prefix##_cd(); void prefix##_ce(); void prefix##_cf(); \ 167 void prefix##_d0(); void prefix##_d1(); void prefix##_d2(); void prefix##_d3(); \ 168 void prefix##_d4(); void prefix##_d5(); void prefix##_d6(); void prefix##_d7(); \ 169 void prefix##_d8(); void prefix##_d9(); void prefix##_da(); void prefix##_db(); \ 170 void prefix##_dc(); void prefix##_dd(); void prefix##_de(); void prefix##_df(); \ 171 void prefix##_e0(); void prefix##_e1(); void prefix##_e2(); void prefix##_e3(); \ 172 void prefix##_e4(); void prefix##_e5(); void prefix##_e6(); void prefix##_e7(); \ 173 void prefix##_e8(); void prefix##_e9(); void prefix##_ea(); void prefix##_eb(); \ 174 void prefix##_ec(); void prefix##_ed(); void prefix##_ee(); void prefix##_ef(); \ 175 void prefix##_f0(); void prefix##_f1(); void prefix##_f2(); void prefix##_f3(); \ 176 void prefix##_f4(); void prefix##_f5(); void prefix##_f6(); void prefix##_f7(); \ 177 void prefix##_f8(); void prefix##_f9(); void prefix##_fa(); void prefix##_fb(); \ 178 void prefix##_fc(); void prefix##_fd(); void prefix##_fe(); void prefix##_ff(); 179 180 PROTOTYPES(op) 181 182 uint32_t translated(uint16_t addr); 183 void h6280_cycles(int cyc); 184 void set_nz(uint8_t n); 185 void clear_t(); 186 void do_interrupt(uint16_t vector); 187 void check_and_take_irq_lines(); 188 void check_irq_lines(); 189 void check_vdc_vce_penalty(uint16_t addr); 190 void bra(bool cond); 191 void ea_zpg(); 192 void ea_tflg(); 193 void ea_zpx(); 194 void ea_zpy(); 195 void ea_abs(); 196 void ea_abx(); 197 void ea_aby(); 198 void ea_zpi(); 199 void ea_idx(); 200 void ea_idy(); 201 void ea_ind(); 202 void ea_iax(); 203 uint8_t rd_imm(); 204 uint8_t rd_zpg(); 205 uint8_t rd_zpx(); 206 uint8_t rd_zpy(); 207 uint8_t rd_abs(); 208 uint8_t rd_abx(); 209 uint8_t rd_aby(); 210 uint8_t rd_zpi(); 211 uint8_t rd_idx(); 212 uint8_t rd_idy(); 213 uint8_t rd_tfl(); 214 void wr_zpg(uint8_t tmp); 215 void wr_zpx(uint8_t tmp); 216 void wr_zpy(uint8_t tmp); 217 void wr_abs(uint8_t tmp); 218 void wr_abx(uint8_t tmp); 219 void wr_aby(uint8_t tmp); 220 void wr_zpi(uint8_t tmp); 221 void wr_idx(uint8_t tmp); 222 void wr_idy(uint8_t tmp); 223 void wb_ea(uint8_t tmp); 224 void wb_eaz(uint8_t tmp); 225 void compose_p(uint8_t set, uint8_t clr); 226 void tadc(uint8_t tmp); 227 void adc(uint8_t tmp); 228 void tand(uint8_t tmp); 229 void and_a(uint8_t tmp); 230 uint8_t asl(uint8_t tmp); 231 void bbr(int bit, uint8_t tmp); 232 void bbs(int bit, uint8_t tmp); 233 void bcc(); 234 void bcs(); 235 void beq(); 236 void bit(uint8_t tmp); 237 void bmi(); 238 void bne(); 239 void bpl(); 240 void brk(); 241 void bsr(); 242 void bvc(); 243 void bvs(); 244 void cla(); 245 void clc(); 246 void cld(); 247 void cli(); 248 void clv(); 249 void clx(); 250 void cly(); 251 void cmp(uint8_t tmp); 252 void cpx(uint8_t tmp); 253 void cpy(uint8_t tmp); 254 uint8_t dec(uint8_t tmp); 255 void dex(); 256 void dey(); 257 void teor(uint8_t tmp); 258 void eor(uint8_t tmp); 259 uint8_t inc(uint8_t tmp); 260 void inx(); 261 void iny(); 262 void jmp(); 263 void jsr(); 264 void lda(uint8_t tmp); 265 void ldx(uint8_t tmp); 266 void ldy(uint8_t tmp); 267 uint8_t lsr(uint8_t tmp); 268 void nop(); 269 void tora(uint8_t tmp); 270 void ora(uint8_t tmp); 271 void pha(); 272 void php(); 273 void phx(); 274 void phy(); 275 void pla(); 276 void plp(); 277 void plx(); 278 void ply(); 279 uint8_t rmb(int bit, uint8_t tmp); 280 uint8_t rol(uint8_t tmp); 281 uint8_t ror(uint8_t tmp); 282 void rti(); 283 void rts(); 284 void sax(); 285 void say(); 286 void tsbc(uint8_t tmp); 287 void sbc(uint8_t tmp); 288 void sec(); 289 void sed(); 290 void sei(); 291 void set(); 292 uint8_t smb(int bit, uint8_t tmp); 293 void st0(uint8_t tmp); 294 void st1(uint8_t tmp); 295 void st2(uint8_t tmp); 296 uint8_t sta(); 297 uint8_t stx(); 298 uint8_t sty(); 299 uint8_t stz(); 300 void sxy(); 301 void tai(); 302 void tam(uint8_t tmp); 303 void tax(); 304 void tay(); 305 void tdd(); 306 void tia(); 307 void tii(); 308 void tin(); 309 void tma(uint8_t tmp); 310 uint8_t trb(uint8_t tmp); 311 uint8_t tsb(uint8_t tmp); 312 void tsx(); 313 void tst(uint8_t imm, uint8_t tmp); 314 void txa(); 315 void txs(); 316 void tya(); 317 void csh(); 318 void csl(); 319 320 enum 321 { 322 H6280_RESET_VEC = 0xfffe, 323 H6280_NMI_VEC = 0xfffc, 324 H6280_TIMER_VEC = 0xfffa, 325 H6280_IRQ1_VEC = 0xfff8, 326 H6280_IRQ2_VEC = 0xfff6 /* Aka BRK vector */ 327 }; 328 329 // address spaces 330 const address_space_config m_program_config; 331 const address_space_config m_io_config; 332 333 // CPU registers 334 PAIR m_ppc; /* previous program counter */ 335 PAIR m_pc; /* program counter */ 336 PAIR m_sp; /* stack pointer (always 100 - 1FF) */ 337 PAIR m_zp; /* zero page address */ 338 PAIR m_ea; /* effective address */ 339 uint8_t m_a; /* Accumulator */ 340 uint8_t m_x; /* X index register */ 341 uint8_t m_y; /* Y index register */ 342 uint8_t m_p; /* Processor status */ 343 uint8_t m_mmr[8]; /* Hu6280 memory mapper registers */ 344 uint8_t m_irq_mask; /* interrupt enable/disable */ 345 uint8_t m_timer_status; /* timer status */ 346 uint8_t m_timer_ack; /* timer acknowledge */ 347 uint8_t m_clocks_per_cycle; /* 4 = low speed mode, 1 = high speed mode */ 348 int32_t m_timer_value; /* timer interrupt */ 349 int32_t m_timer_load; /* reload value */ 350 uint8_t m_nmi_state; 351 uint8_t m_irq_state[3]; 352 uint8_t m_irq_pending; 353 #if H6280_LAZY_FLAGS 354 int32_t m_nz; /* last value (lazy N and Z flag) */ 355 #endif 356 uint8_t m_io_buffer; /* last value written to the PSG, timer, and interrupt pages */ 357 358 // internal registers 359 void internal_map(address_map &map); 360 uint8_t irq_status_r(offs_t offset); 361 void irq_status_w(offs_t offset, uint8_t data); 362 363 uint8_t timer_r(); 364 void timer_w(offs_t offset, uint8_t data); 365 366 uint8_t port_r(); 367 void port_w(uint8_t data); 368 369 uint8_t io_buffer_r(); 370 void psg_w(offs_t offset, uint8_t data); 371 372 devcb_read8 m_port_in_cb; 373 devcb_write8 m_port_out_cb; 374 375 required_device<c6280_device> m_psg; 376 377 // other internal states 378 int m_icount; 379 380 uint8_t m_timer_scale; 381 382 // address spaces 383 memory_access<21, 0, 0, ENDIANNESS_LITTLE>::cache m_cache; 384 memory_access<21, 0, 0, ENDIANNESS_LITTLE>::specific m_program; 385 memory_access< 2, 0, 0, ENDIANNESS_LITTLE>::specific m_io; 386 387 typedef void (h6280_device::*ophandler)(); 388 389 ophandler m_opcode[256]; 390 391 static const ophandler s_opcodetable[256]; 392 }; 393 394 DECLARE_DEVICE_TYPE(H6280, h6280_device) 395 396 #endif // MAME_CPU_H6280_H6280_H 397