// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** ppc.h Interface file for the universal machine language-based PowerPC emulator. ***************************************************************************/ #pragma once #ifndef __PPC_H__ #define __PPC_H__ #include "divtlb.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" /*************************************************************************** CONSTANTS ***************************************************************************/ /* general constants */ #define PPC_MAX_FASTRAM 4 #define PPC_MAX_HOTSPOTS 16 /* interrupt types */ #define PPC_IRQ 0 /* external IRQ */ #define PPC_IRQ_LINE_0 0 /* (4XX) external IRQ0 */ #define PPC_IRQ_LINE_1 1 /* (4XX) external IRQ1 */ #define PPC_IRQ_LINE_2 2 /* (4XX) external IRQ2 */ #define PPC_IRQ_LINE_3 3 /* (4XX) external IRQ3 */ #define PPC_IRQ_LINE_4 4 /* (4XX) external IRQ4 */ /* register enumeration */ enum { PPC_PC = 1, PPC_R0, PPC_R1, PPC_R2, PPC_R3, PPC_R4, PPC_R5, PPC_R6, PPC_R7, PPC_R8, PPC_R9, PPC_R10, PPC_R11, PPC_R12, PPC_R13, PPC_R14, PPC_R15, PPC_R16, PPC_R17, PPC_R18, PPC_R19, PPC_R20, PPC_R21, PPC_R22, PPC_R23, PPC_R24, PPC_R25, PPC_R26, PPC_R27, PPC_R28, PPC_R29, PPC_R30, PPC_R31, PPC_CR, PPC_LR, PPC_CTR, PPC_XER, PPC_F0, PPC_F1, PPC_F2, PPC_F3, PPC_F4, PPC_F5, PPC_F6, PPC_F7, PPC_F8, PPC_F9, PPC_F10, PPC_F11, PPC_F12, PPC_F13, PPC_F14, PPC_F15, PPC_F16, PPC_F17, PPC_F18, PPC_F19, PPC_F20, PPC_F21, PPC_F22, PPC_F23, PPC_F24, PPC_F25, PPC_F26, PPC_F27, PPC_F28, PPC_F29, PPC_F30, PPC_F31, PPC_FPSCR, PPC_MSR, PPC_SRR0, PPC_SRR1, PPC_SPRG0, PPC_SPRG1, PPC_SPRG2, PPC_SPRG3, PPC_SDR1, PPC_EXIER, PPC_EXISR, PPC_EVPR, PPC_IOCR, PPC_TBL, PPC_TBH, PPC_DEC, PPC_SR0, PPC_SR1, PPC_SR2, PPC_SR3, PPC_SR4, PPC_SR5, PPC_SR6, PPC_SR7, PPC_SR8, PPC_SR9, PPC_SR10, PPC_SR11, PPC_SR12, PPC_SR13, PPC_SR14, PPC_SR15 }; /* compiler-specific options */ #define PPCDRC_STRICT_VERIFY 0x0001 /* verify all instructions */ #define PPCDRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */ #define PPCDRC_ACCURATE_SINGLES 0x0004 /* do excessive rounding to make single-precision results "accurate" */ /* common sets of options */ #define PPCDRC_COMPATIBLE_OPTIONS (PPCDRC_STRICT_VERIFY | PPCDRC_FLUSH_PC | PPCDRC_ACCURATE_SINGLES) #define PPCDRC_FASTEST_OPTIONS (0) /*************************************************************************** PUBLIC FUNCTIONS ***************************************************************************/ #define MCFG_PPC_BUS_FREQUENCY(_frequency) \ ppc_device::set_bus_frequency(*device, _frequency); class ppc_frontend; class ppc_device : public cpu_device, public device_vtlb_interface { friend class ppc_frontend; protected: /* PowerPC flavors */ enum powerpc_flavor { PPC_MODEL_403GA = 0x00200000, PPC_MODEL_403GB = 0x00200100, PPC_MODEL_403GC = 0x00200200, PPC_MODEL_403GCX = 0x00201400, PPC_MODEL_405GP = 0x40110000, PPC_MODEL_601 = 0x00010000, PPC_MODEL_603 = 0x00030000, /* "Wart" */ PPC_MODEL_604 = 0x00040000, /* "Zephyr" */ PPC_MODEL_602 = 0x00050200, /* "Galahad" */ PPC_MODEL_603E = 0x00060103, /* "Stretch", version 1.3 */ PPC_MODEL_603EV = 0x00070000, /* "Valiant" */ PPC_MODEL_603R = 0x00071202, /* "Goldeneye", version 2.1 */ PPC_MODEL_740 = 0x00080301, /* "Arthur", version 3.1 */ PPC_MODEL_750 = PPC_MODEL_740, PPC_MODEL_740P = 0x00080202, /* "Conan Doyle", version 1.2 */ PPC_MODEL_750P = PPC_MODEL_740P, PPC_MODEL_755 = 0x00083203, /* "Goldfinger", version 2.3 */ PPC_MODEL_7400 = 0x000c0209, /* "Max", version 2.9 */ PPC_MODEL_7410 = 0x800c1104, /* "Nitro", version 3.4 */ PPC_MODEL_7450 = 0x80000201, /* "Vger", version 2.1 */ PPC_MODEL_7451 = 0x80000203, /* "Vger", version 2.3 */ PPC_MODEL_7441 = PPC_MODEL_7451, PPC_MODEL_7455 = 0x80010303, /* "Apollo 6", version 3.3 */ PPC_MODEL_7445 = PPC_MODEL_7455, PPC_MODEL_7457 = 0x80020101, /* "Apollo 7", version 1.1 */ PPC_MODEL_MPC8240 = 0x00810101, /* "Kahlua" */ PPC_MODEL_MPC8241 = 0x80811014, /* "Kahlua Lt" */ PPC_MODEL_MPC8245 = 0x80811014 /* "Kahlua II" */ }; public: // construction/destruction ppc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, int address_bits, int data_bits, powerpc_flavor flavor, uint32_t cap, uint32_t tb_divisor, address_map_constructor internal_map); static void set_bus_frequency(device_t &device, uint32_t bus_frequency) { downcast(device).c_bus_frequency = bus_frequency; } void ppc_set_dcstore_callback(write32_delegate callback); void ppcdrc_set_options(uint32_t options); void ppcdrc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); void ppcdrc_add_hotspot(offs_t pc, uint32_t opcode, uint32_t cycles); TIMER_CALLBACK_MEMBER(decrementer_int_callback); TIMER_CALLBACK_MEMBER(ppc4xx_buffered_dma_callback); TIMER_CALLBACK_MEMBER(ppc4xx_fit_callback); TIMER_CALLBACK_MEMBER(ppc4xx_pit_callback); TIMER_CALLBACK_MEMBER(ppc4xx_spu_callback); void ppc_cfunc_printf_exception(); void ppc_cfunc_printf_debug(); void ppc_cfunc_printf_probe(); void ppc_cfunc_unimplemented(); void ppccom_tlb_fill(); void ppccom_update_fprf(); void ppccom_dcstore_callback(); void ppccom_execute_tlbie(); void ppccom_execute_tlbia(); void ppccom_execute_tlbl(); void ppccom_execute_mfspr(); void ppccom_execute_mftb(); void ppccom_execute_mtspr(); void ppccom_tlb_flush(); void ppccom_execute_mfdcr(); void ppccom_execute_mtdcr(); void ppccom_get_dsisr(); protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_stop() override; // device_execute_interface overrides virtual uint32_t execute_min_cycles() const override { return 1; } virtual uint32_t execute_max_cycles() const override { return 40; } virtual uint32_t execute_input_lines() const override { return 1; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; // device_memory_interface overrides virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : nullptr; } virtual bool memory_translate(address_spacenum spacenum, int intention, offs_t &address) override; // device_state_interface overrides virtual void state_export(const device_state_entry &entry) override; virtual void state_import(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides virtual uint32_t disasm_min_opcode_bytes() const override { return 4; } virtual uint32_t disasm_max_opcode_bytes() const override { return 4; } virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; /* exception types */ enum { EXCEPTION_RESET = 1, EXCEPTION_MACHCHECK = 2, EXCEPTION_DSI = 3, /* PPCCAP_OEA */ EXCEPTION_PROTECTION = 3, /* PPCCAP_4XX */ EXCEPTION_ISI = 4, EXCEPTION_EI = 5, EXCEPTION_ALIGN = 6, EXCEPTION_PROGRAM = 7, EXCEPTION_NOFPU = 8, EXCEPTION_DECREMENT = 9, EXCEPTION_SYSCALL = 12, EXCEPTION_TRACE = 13, EXCEPTION_FPASSIST = 14, EXCEPTION_ITLBMISS = 16, /* PPCCAP_603_MMU */ EXCEPTION_DTLBMISSL = 17, /* PPCCAP_603_MMU */ EXCEPTION_DTLBMISSS = 18, /* PPCCAP_603_MMU */ EXCEPTION_COUNT }; address_space_config m_program_config; address_space *m_program; uint32_t c_bus_frequency; struct internal_ppc_state { uint32_t pc; uint32_t r[32]; double f[32]; uint32_t cr[8]; uint32_t fpscr; uint32_t msr; uint32_t xerso; uint32_t sr[16]; uint32_t spr[1024]; int icount; uint32_t mode; /* current global mode */ uint32_t irq_pending; /* parameters for calls */ uint32_t param0; uint32_t param1; /* PowerPC 603-specific state */ uint32_t mmu603_cmp; uint32_t mmu603_hash[2]; uint32_t mmu603_r[4]; /* parameters for subroutines */ uint32_t tempaddr; /* temporary address storage */ drcuml_ireg tempdata; /* temporary data storage */ uint32_t updateaddr; /* update address storage */ uint32_t swcount; /* counter for sw instructions */ const char * format; /* format string for printing */ uint32_t arg0; /* print_debug argument 1 */ double fp0; /* floating point 0 */ }; internal_ppc_state *m_core; int m_ppc_tb_base_icount; int m_ppc_dec_base_icount; int m_ppc_dec_trigger_cycle; int m_bus_freq_multiplier; uint32_t m_npc; uint32_t m_dcr[256]; uint32_t m_lr; uint32_t m_ctr; uint32_t m_xer; uint32_t m_pvr; uint32_t m_srr0; uint32_t m_srr1; uint32_t m_srr2; uint32_t m_srr3; uint32_t m_hid0; uint32_t m_hid1; uint32_t m_hid2; uint32_t m_sdr1; uint32_t m_sprg[4]; uint32_t m_dsisr; uint32_t m_dar; uint32_t m_ear; uint32_t m_dmiss; uint32_t m_dcmp; uint32_t m_hash1; uint32_t m_hash2; uint32_t m_imiss; uint32_t m_icmp; uint32_t m_rpa; struct BATENT { uint32_t u; uint32_t l; }; BATENT m_ibat[4]; BATENT m_dbat[4]; uint32_t m_evpr; uint32_t m_exier; uint32_t m_exisr; uint32_t m_bear; uint32_t m_besr; uint32_t m_iocr; uint32_t m_br[8]; uint32_t m_iabr; uint32_t m_esr; uint32_t m_iccr; uint32_t m_dccr; uint32_t m_pit; uint32_t m_pit_counter; uint32_t m_pit_int_enable; uint32_t m_tsr; uint32_t m_dbsr; uint32_t m_sgr; uint32_t m_pid; uint32_t m_pbl1; uint32_t m_pbl2; uint32_t m_pbu1; uint32_t m_pbu2; uint32_t m_fit_bit; uint32_t m_fit_int_enable; uint32_t m_wdt_bit; uint32_t m_wdt_int_enable; uint32_t m_dac1; uint32_t m_dac2; uint32_t m_iac1; uint32_t m_iac2; struct SPU_REGS { uint8_t spls; uint8_t sphs; uint16_t brd; uint8_t spctl; uint8_t sprc; uint8_t sptc; uint8_t sprb; uint8_t sptb; emu_timer *rx_timer; emu_timer *tx_timer; }; SPU_REGS m_spu_old; struct DMA_REGS { uint32_t cr; uint32_t da; uint32_t sa; uint32_t ct; uint32_t cc; }; DMA_REGS m_dma[4]; uint32_t m_dmasr; int m_reserved; uint32_t m_reserved_address; int m_interrupt_pending; uint64_t m_tb; /* 56-bit timebase register */ // STUFF added for the 6xx series uint32_t m_dec, m_dec_frac; union FPR { uint64_t id; double fd; }; union FPR32 { uint32_t i; float f; }; FPR m_fpr[32]; int m_is603; int m_is602; /* PowerPC 602 specific registers */ uint32_t m_lt; uint32_t m_sp; uint32_t m_tcr; uint32_t m_ibr; uint32_t m_esasrr; uint32_t m_sebr; uint32_t m_ser; /* architectural distinctions */ powerpc_flavor m_flavor; uint32_t m_cap; uint8_t m_cache_line_size; uint32_t m_tb_divisor; /* PowerPC 4xx-specific state */ /* PowerPC 4XX-specific serial port state */ struct ppc4xx_spu_state { uint8_t regs[9]; uint8_t txbuf; uint8_t rxbuf; emu_timer * timer; uint8_t rxbuffer[256]; uint32_t rxin, rxout; write8_delegate tx_cb; }; ppc4xx_spu_state m_spu; emu_timer * m_fit_timer; emu_timer * m_pit_timer; emu_timer * m_wdog_timer; uint32_t m_pit_reload; uint32_t m_irqstate; emu_timer * m_buffered_dma_timer[4]; int m_buffered_dma_rate[4]; /* internal stuff */ direct_read_data *m_direct; offs_t m_codexor; uint32_t m_system_clock; uint32_t m_cpu_clock; uint64_t m_tb_zero_cycles; uint64_t m_dec_zero_cycles; emu_timer * m_decrementer_int_timer; read32_delegate m_dcr_read_func; write32_delegate m_dcr_write_func; write32_delegate m_dcstore_cb; read32_delegate m_ext_dma_read_cb[4]; write32_delegate m_ext_dma_write_cb[4]; /* PowerPC function pointers for memory accesses/exceptions */ #ifdef PPC_H_INCLUDED_FROM_PPC_C jmp_buf m_exception_jmpbuf; #endif uint8_t (*m_ppcread8)(address_space &space, offs_t address); uint16_t (*m_ppcread16)(address_space &space, offs_t address); uint32_t (*m_ppcread32)(address_space &space, offs_t address); uint64_t (*m_ppcread64)(address_space &space, offs_t address); void (*m_ppcwrite8)(address_space &space, offs_t address, uint8_t data); void (*m_ppcwrite16)(address_space &space, offs_t address, uint16_t data); void (*m_ppcwrite32)(address_space &space, offs_t address, uint32_t data); void (*m_ppcwrite64)(address_space &space, offs_t address, uint64_t data); uint16_t (*m_ppcread16_unaligned)(address_space &space, offs_t address); uint32_t (*m_ppcread32_unaligned)(address_space &space, offs_t address); uint64_t (*m_ppcread64_unaligned)(address_space &space, offs_t address); void (*m_ppcwrite16_unaligned)(address_space &space, offs_t address, uint16_t data); void (*m_ppcwrite32_unaligned)(address_space &space, offs_t address, uint32_t data); void (*m_ppcwrite64_unaligned)(address_space &space, offs_t address, uint64_t data); void (*m_optable19[1024])(uint32_t); void (*m_optable31[1024])(uint32_t); void (*m_optable59[1024])(uint32_t); void (*m_optable63[1024])(uint32_t); void (*m_optable[64])(uint32_t); /* core state */ drc_cache m_cache; /* pointer to the DRC code cache */ std::unique_ptr m_drcuml; /* DRC UML generator state */ std::unique_ptr m_drcfe; /* pointer to the DRC front-end state */ uint32_t m_drcoptions; /* configurable DRC options */ /* parameters for subroutines */ uint32_t m_arg1; /* print_debug argument 2 */ /* tables */ uint8_t m_fpmode[4]; /* FPU mode table */ uint8_t m_sz_cr_table[32]; /* SZ CR table */ uint8_t m_cmp_cr_table[32]; /* CMP CR table */ uint8_t m_cmpl_cr_table[32]; /* CMPL CR table */ uint8_t m_fcmp_cr_table[32]; /* FCMP CR table */ /* internal stuff */ uint8_t m_cache_dirty; /* true if we need to flush the cache */ /* register mappings */ uml::parameter m_regmap[32]; /* parameter to register mappings for all 32 integer registers */ uml::parameter m_fdregmap[32]; /* parameter to register mappings for all 32 floating point registers */ /* subroutines */ uml::code_handle * m_entry; /* entry point */ uml::code_handle * m_nocode; /* nocode exception handler */ uml::code_handle * m_out_of_cycles; /* out of cycles exception handler */ uml::code_handle * m_tlb_mismatch; /* tlb mismatch handler */ uml::code_handle * m_swap_tgpr; /* swap TGPR handler */ uml::code_handle * m_lsw[8][32]; /* lsw entries */ uml::code_handle * m_stsw[8][32]; /* stsw entries */ uml::code_handle * m_read8[8]; /* read byte */ uml::code_handle * m_write8[8]; /* write byte */ uml::code_handle * m_read16[8]; /* read half */ uml::code_handle * m_read16mask[8]; /* read half */ uml::code_handle * m_write16[8]; /* write half */ uml::code_handle * m_write16mask[8]; /* write half */ uml::code_handle * m_read32[8]; /* read word */ uml::code_handle * m_read32align[8]; /* read word aligned */ uml::code_handle * m_read32mask[8]; /* read word */ uml::code_handle * m_write32[8]; /* write word */ uml::code_handle * m_write32align[8]; /* write word aligned */ uml::code_handle * m_write32mask[8]; /* write word */ uml::code_handle * m_read64[8]; /* read double */ uml::code_handle * m_read64mask[8]; /* read double */ uml::code_handle * m_write64[8]; /* write double */ uml::code_handle * m_write64mask[8]; /* write double */ uml::code_handle * m_exception[EXCEPTION_COUNT]; /* array of exception handlers */ uml::code_handle * m_exception_norecover[EXCEPTION_COUNT]; /* array of exception handlers */ /* fast RAM */ /* fast RAM info */ struct fast_ram_info { offs_t start; /* start of the RAM block */ offs_t end; /* end of the RAM block */ bool readonly; /* true if read-only */ void * base; /* base in memory where the RAM lives */ }; uint32_t m_fastram_select; fast_ram_info m_fastram[PPC_MAX_FASTRAM]; /* hotspots */ /* hotspot info */ struct hotspot_info { offs_t pc; /* PC to consider */ uint32_t opcode; /* required opcode at that PC */ uint32_t cycles; /* number of cycles to eat when hit */ }; uint32_t m_hotspot_select; hotspot_info m_hotspot[PPC_MAX_HOTSPOTS]; uint64_t m_debugger_temp; /* internal compiler state */ struct compiler_state { uint32_t cycles; /* accumulated cycles */ uint8_t checkints; /* need to check interrupts before next instruction */ uint8_t checksoftints; /* need to check software interrupts before next instruction */ uml::code_label labelnum; /* index for local labels */ }; uint32_t get_cr(); void set_cr(uint32_t value); uint32_t get_xer(); void set_xer(uint32_t value); uint64_t get_timebase(); void set_timebase(uint64_t newtb); uint32_t get_decrementer(); void set_decrementer(uint32_t newdec); uint32_t ppccom_translate_address_internal(int intention, offs_t &address); void ppc4xx_set_irq_line(uint32_t bitmask, int state); int ppc4xx_get_irq_line(uint32_t bitmask); void ppc4xx_dma_update_irq_states(); bool ppc4xx_dma_decrement_count(int dmachan); bool ppc4xx_dma_fetch_transmit_byte(int dmachan, uint8_t *byte); bool ppc4xx_dma_handle_receive_byte(int dmachan, uint8_t byte); void ppc4xx_dma_exec(int dmachan); void ppc4xx_spu_update_irq_states(); void ppc4xx_spu_rx_data(uint8_t data); void ppc4xx_spu_timer_reset(); void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name); void load_fast_iregs(drcuml_block *block); void save_fast_iregs(drcuml_block *block); void load_fast_fregs(drcuml_block *block); void save_fast_fregs(drcuml_block *block); uint32_t compute_rlw_mask(uint8_t mb, uint8_t me); uint32_t compute_crf_mask(uint8_t crm); uint32_t compute_spr(uint32_t spr); void code_flush_cache(); void code_compile_block(uint8_t mode, offs_t pc); void static_generate_entry_point(); void static_generate_nocode_handler(); void static_generate_out_of_cycles(); void static_generate_tlb_mismatch(); void static_generate_exception(uint8_t exception, int recover, const char *name); void static_generate_memory_accessor(int mode, int size, int iswrite, int ismasked, const char *name, uml::code_handle *&handleptr, uml::code_handle *masked); void static_generate_swap_tgpr(); void static_generate_lsw_entries(int mode); void static_generate_stsw_entries(int mode); void generate_update_mode(drcuml_block *block); void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception); void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_compute_flags(drcuml_block *block, const opcode_desc *desc, int updatecr, uint32_t xermask, int invertcarry); void generate_shift_flags(drcuml_block *block, const opcode_desc *desc, uint32_t op); void generate_fp_flags(drcuml_block *block, const opcode_desc *desc, int updatefprf); void generate_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int source, uint8_t link); void generate_branch_bo(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t bo, uint32_t bi, int source, int link); bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); bool generate_instruction_13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); bool generate_instruction_1f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); bool generate_instruction_3b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); bool generate_instruction_3f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op); const char *log_desc_flags_to_string(uint32_t flags); void log_register_list(drcuml_state *drcuml, const char *string, const uint32_t *reglist, const uint32_t *regnostarlist); void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent); }; //class ppc403_device : public ppc_device //{ //public: // ppc403_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // //protected: // virtual uint32_t execute_input_lines() const { return 8; } //}; // // //class ppc405_device : public ppc_device //{ //public: // ppc405_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // //protected: // virtual uint32_t execute_input_lines() const { return 8; } //}; class ppc603_device : public ppc_device { public: ppc603_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc603e_device : public ppc_device { public: ppc603e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc603r_device : public ppc_device { public: ppc603r_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc602_device : public ppc_device { public: ppc602_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class mpc8240_device : public ppc_device { public: mpc8240_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc601_device : public ppc_device { public: ppc601_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc604_device : public ppc_device { public: ppc604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc4xx_device : public ppc_device { public: ppc4xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, powerpc_flavor flavor, uint32_t cap, uint32_t tb_divisor); void ppc4xx_spu_set_tx_handler(write8_delegate callback); void ppc4xx_spu_receive_byte(uint8_t byteval); void ppc4xx_set_dma_read_handler(int channel, read32_delegate callback, int rate); void ppc4xx_set_dma_write_handler(int channel, write32_delegate callback, int rate); void ppc4xx_set_dcr_read_handler(read32_delegate dcr_read_func); void ppc4xx_set_dcr_write_handler(write32_delegate dcr_write_func); DECLARE_READ8_MEMBER( ppc4xx_spu_r ); DECLARE_WRITE8_MEMBER( ppc4xx_spu_w ); protected: virtual uint32_t execute_input_lines() const override { return 5; } virtual void execute_set_input(int inputnum, int state) override; }; class ppc403ga_device : public ppc4xx_device { public: ppc403ga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc403gcx_device : public ppc4xx_device { public: ppc403gcx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; class ppc405gp_device : public ppc4xx_device { public: ppc405gp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; extern const device_type PPC601; extern const device_type PPC602; extern const device_type PPC603; extern const device_type PPC603E; extern const device_type PPC603R; extern const device_type PPC604; extern const device_type MPC8240; extern const device_type PPC403GA; extern const device_type PPC403GCX; extern const device_type PPC405GP; #endif /* __PPC_H__ */