From b7a49aff4ab7c3daa34bf1c9fa117db6d67c9401 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 3 Apr 2019 20:17:07 -0400 Subject: mc68328: Improve integration of emulated device (nw) - Derive class from m68000_device instead of using CPU finder - Internalize read/write handlers and mapping for on-chip registers - Read video memory from cached address space instead of hardcoded RAM device in screen_update - Generate vectors upon interrupt acknowledgment instead of using set_input_line_and_vector - Mask out low 3 bits of IVR - Move callback resolution to device_resolve_objects --- src/devices/machine/mc68328.cpp | 80 +++++++++++++++++++++++++++-------------- src/devices/machine/mc68328.h | 23 ++++++------ src/mame/drivers/palm.cpp | 33 +++++++---------- 3 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/devices/machine/mc68328.cpp b/src/devices/machine/mc68328.cpp index 96d91ccb175..6f453483102 100644 --- a/src/devices/machine/mc68328.cpp +++ b/src/devices/machine/mc68328.cpp @@ -10,8 +10,6 @@ #include "emu.h" #include "machine/mc68328.h" -#include "cpu/m68000/m68000.h" -#include "machine/ram.h" #define SCR_BETO 0x80 @@ -350,8 +348,14 @@ static inline void ATTR_PRINTF(3,4) verboselog(device_t &device, int n_level, co DEFINE_DEVICE_TYPE(MC68328, mc68328_device, "mc68328", "MC68328 DragonBall Integrated Processor") +void mc68328_device::internal_map(address_map &map) +{ + map(0xfff000, 0xffffff).rw(FUNC(mc68328_device::internal_read), FUNC(mc68328_device::internal_write)); +} + + mc68328_device::mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, MC68328, tag, owner, clock) + : m68000_device(mconfig, tag, owner, clock, MC68328, 16, 24, address_map_constructor(FUNC(mc68328_device::internal_map), this)) , m_rtc(nullptr), m_pwm(nullptr) , m_out_port_a_cb(*this) , m_out_port_b_cb(*this) @@ -377,16 +381,19 @@ mc68328_device::mc68328_device(const machine_config &mconfig, const char *tag, d , m_out_spim_cb(*this) , m_in_spim_cb(*this) , m_spim_xch_trigger_cb(*this) - , m_cpu(*this, finder_base::DUMMY_TAG) { } //------------------------------------------------- -// device_start - device-specific startup +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time //------------------------------------------------- -void mc68328_device::device_start() +void mc68328_device::device_resolve_objects() { + m68000_device::device_resolve_objects(); + m_out_port_a_cb.resolve(); m_out_port_b_cb.resolve(); m_out_port_c_cb.resolve(); @@ -415,6 +422,15 @@ void mc68328_device::device_start() m_in_spim_cb.resolve(); m_spim_xch_trigger_cb.resolve(); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc68328_device::device_start() +{ + m68000_device::device_start(); m_gptimer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::timer1_hit),this)); m_gptimer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68328_device::timer2_hit),this)); @@ -430,6 +446,10 @@ void mc68328_device::device_start() void mc68328_device::device_reset() { + m68000_device::device_reset(); + + m_int_ack_callback = device_irq_acknowledge_delegate(FUNC(mc68328_device::vector_gen), this); + m_regs.scr = 0x0c; m_regs.grpbasea = 0x0000; m_regs.grpbaseb = 0x0000; @@ -575,31 +595,31 @@ void mc68328_device::set_interrupt_line(uint32_t line, uint32_t active) if (m_regs.isr & INT_M68K_LINE7) { - m_cpu->set_input_line_and_vector(M68K_IRQ_7, ASSERT_LINE, m_regs.ivr | 0x07); + set_input_line(M68K_IRQ_7, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE6) { - m_cpu->set_input_line_and_vector(M68K_IRQ_6, ASSERT_LINE, m_regs.ivr | 0x06); + set_input_line(M68K_IRQ_6, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE5) { - m_cpu->set_input_line_and_vector(M68K_IRQ_5, ASSERT_LINE, m_regs.ivr | 0x05); + set_input_line(M68K_IRQ_5, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE4) { - m_cpu->set_input_line_and_vector(M68K_IRQ_4, ASSERT_LINE, m_regs.ivr | 0x04); + set_input_line(M68K_IRQ_4, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE3) { - m_cpu->set_input_line_and_vector(M68K_IRQ_3, ASSERT_LINE, m_regs.ivr | 0x03); + set_input_line(M68K_IRQ_3, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE2) { - m_cpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, m_regs.ivr | 0x02); + set_input_line(M68K_IRQ_2, ASSERT_LINE); } else if (m_regs.isr & INT_M68K_LINE1) { - m_cpu->set_input_line_and_vector(M68K_IRQ_1, ASSERT_LINE, m_regs.ivr | 0x01); + set_input_line(M68K_IRQ_1, ASSERT_LINE); } } } @@ -609,31 +629,31 @@ void mc68328_device::set_interrupt_line(uint32_t line, uint32_t active) if ((line & INT_M68K_LINE7) && !(m_regs.isr & INT_M68K_LINE7)) { - m_cpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); + set_input_line(M68K_IRQ_7, CLEAR_LINE); } if ((line & INT_M68K_LINE6) && !(m_regs.isr & INT_M68K_LINE6)) { - m_cpu->set_input_line(M68K_IRQ_6, CLEAR_LINE); + set_input_line(M68K_IRQ_6, CLEAR_LINE); } if ((line & INT_M68K_LINE5) && !(m_regs.isr & INT_M68K_LINE5)) { - m_cpu->set_input_line(M68K_IRQ_5, CLEAR_LINE); + set_input_line(M68K_IRQ_5, CLEAR_LINE); } if ((line & INT_M68K_LINE4) && !(m_regs.isr & INT_M68K_LINE4)) { - m_cpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); + set_input_line(M68K_IRQ_4, CLEAR_LINE); } if ((line & INT_M68K_LINE3) && !(m_regs.isr & INT_M68K_LINE3)) { - m_cpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); + set_input_line(M68K_IRQ_3, CLEAR_LINE); } if ((line & INT_M68K_LINE2) && !(m_regs.isr & INT_M68K_LINE2)) { - m_cpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); + set_input_line(M68K_IRQ_2, CLEAR_LINE); } if ((line & INT_M68K_LINE1) && !(m_regs.isr & INT_M68K_LINE1)) { - m_cpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + set_input_line(M68K_IRQ_1, CLEAR_LINE); } } } @@ -685,6 +705,11 @@ void mc68328_device::set_port_d_lines(uint8_t state, int bit) poll_port_d_interrupts(); } +IRQ_CALLBACK_MEMBER( mc68328_device::vector_gen ) +{ + return m_regs.ivr | irqline; +} + uint32_t mc68328_device::get_timer_frequency(uint32_t index) { uint32_t frequency = 0; @@ -918,7 +943,7 @@ TIMER_CALLBACK_MEMBER( mc68328_device::rtc_tick ) } } -WRITE16_MEMBER( mc68328_device::write ) +void mc68328_device::internal_write(offs_t offset, uint16_t data, uint16_t mem_mask) { uint32_t address = offset << 1; uint16_t temp16[4] = { 0 }; @@ -1198,8 +1223,8 @@ WRITE16_MEMBER( mc68328_device::write ) } else { - verboselog( *this, 2, "mc68328_w: IVR = %02x\n", (data >> 8) & 0x00ff); - m_regs.ivr = (data >> 8) & 0x00ff; + verboselog( *this, 2, "mc68328_w: IVR = %02x\n", (data >> 8) & 0x00f8); + m_regs.ivr = (data >> 8) & 0x00f8; } break; @@ -2112,7 +2137,7 @@ WRITE16_MEMBER( mc68328_device::write ) } } -READ16_MEMBER( mc68328_device::read ) +uint16_t mc68328_device::internal_read(offs_t offset, uint16_t mem_mask) { uint16_t temp16; uint32_t address = offset << 1; @@ -3014,7 +3039,8 @@ READ16_MEMBER( mc68328_device::read ) /* THIS IS PRETTY MUCH TOTALLY WRONG AND DOESN'T REFLECT THE MC68328'S INTERNAL FUNCTIONALITY AT ALL! */ uint32_t mc68328_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t *video_ram = (uint16_t *)(machine().device(RAM_TAG)->pointer() + (m_regs.lssa & 0x00ffffff)); + auto mcache = space(AS_PROGRAM).cache<1, 0, ENDIANNESS_BIG>(); + uint32_t vram_addr = m_regs.lssa & 0x00fffffe; uint16_t word; uint16_t *line; int y, x, b; @@ -3025,9 +3051,9 @@ uint32_t mc68328_device::screen_update(screen_device &screen, bitmap_ind16 &bitm { line = &bitmap.pix16(y); - for (x = 0; x < 160; x += 16) + for (x = 0; x < 160; x += 16, vram_addr += 2) { - word = *(video_ram++); + word = mcache->read_word(vram_addr); for (b = 0; b < 16; b++) { line[x + b] = (word >> (15 - b)) & 0x0001; diff --git a/src/devices/machine/mc68328.h b/src/devices/machine/mc68328.h index d9b169b5324..42708bb18c1 100644 --- a/src/devices/machine/mc68328.h +++ b/src/devices/machine/mc68328.h @@ -87,17 +87,12 @@ #ifndef MAME_MACHINE_MC68328_H #define MAME_MACHINE_MC68328_H +#include "cpu/m68000/m68000.h" -class mc68328_device : public device_t + +class mc68328_device : public m68000_device { public: - template - mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cpu_tag) - : mc68328_device(mconfig, tag, owner, clock) - { - m_cpu.set_tag(std::forward(cpu_tag)); - } - mc68328_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); auto out_port_a() { return m_out_port_a_cb.bind(); } @@ -125,9 +120,6 @@ public: auto in_spim() { return m_in_spim_cb.bind(); } auto spim_xch_trigger() { return m_spim_xch_trigger_cb.bind(); } - - DECLARE_WRITE16_MEMBER(write); - DECLARE_READ16_MEMBER(read); DECLARE_WRITE_LINE_MEMBER(set_penirq_line); void set_port_d_lines(uint8_t state, int bit); @@ -135,6 +127,7 @@ public: protected: // device-level overrides + virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; @@ -332,9 +325,12 @@ private: uint8_t unused42[1260]; }; + void internal_map(address_map &map); + // internal state void set_interrupt_line(uint32_t line, uint32_t active); void poll_port_d_interrupts(); + IRQ_CALLBACK_MEMBER(vector_gen); uint32_t get_timer_frequency(uint32_t index); void maybe_start_timer(uint32_t index, uint32_t new_enable); void timer_compare_event(uint32_t index); @@ -346,6 +342,9 @@ private: TIMER_CALLBACK_MEMBER(pwm_transition); TIMER_CALLBACK_MEMBER(rtc_tick); + void internal_write(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff); + uint16_t internal_read(offs_t offset, uint16_t mem_mask = 0xffff); + mc68328_regs_t m_regs; emu_timer *m_gptimer[2]; @@ -380,8 +379,6 @@ private: devcb_read16 m_in_spim_cb; /* 16-bit input */ devcb_write_line m_spim_xch_trigger_cb; /* SPIM exchange trigger */ /*todo: not really a write line, fix*/ - - required_device m_cpu; }; diff --git a/src/mame/drivers/palm.cpp b/src/mame/drivers/palm.cpp index 1b69491e78a..bb88f10700f 100644 --- a/src/mame/drivers/palm.cpp +++ b/src/mame/drivers/palm.cpp @@ -21,15 +21,12 @@ #include "screen.h" #include "speaker.h" -#define MC68328_TAG "dragonball" - class palm_state : public driver_device { public: palm_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), - m_lsi(*this, MC68328_TAG), m_ram(*this, RAM_TAG), m_io_penx(*this, "PENX"), m_io_peny(*this, "PENY"), @@ -64,8 +61,7 @@ private: offs_t palm_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); void palm_map(address_map &map); - required_device m_maincpu; - required_device m_lsi; + required_device m_maincpu; required_device m_ram; uint8_t m_port_f_latch; uint16_t m_spim_data; @@ -85,15 +81,15 @@ INPUT_CHANGED_MEMBER(palm_state::pen_check) uint8_t button = m_io_penb->read(); if(button) - m_lsi->set_penirq_line(1); + m_maincpu->set_penirq_line(1); else - m_lsi->set_penirq_line(0); + m_maincpu->set_penirq_line(0); } INPUT_CHANGED_MEMBER(palm_state::button_check) { uint8_t button_state = m_io_portd->read(); - m_lsi->set_port_d_lines(button_state, (int)(uintptr_t)param); + m_maincpu->set_port_d_lines(button_state, (int)(uintptr_t)param); } WRITE8_MEMBER(palm_state::palm_port_f_out) @@ -174,7 +170,6 @@ void palm_state::palm_palette(palette_device &palette) const void palm_state::palm_map(address_map &map) { map(0xc00000, 0xe07fff).rom().region("bios", 0); - map(0xfff000, 0xffffff).rw(m_lsi, FUNC(mc68328_device::read), FUNC(mc68328_device::write)); } @@ -185,9 +180,16 @@ void palm_state::palm_map(address_map &map) void palm_state::palm(machine_config &config) { /* basic machine hardware */ - M68000(config, m_maincpu, 32768*506); /* 16.580608 MHz */ + MC68328(config, m_maincpu, 32768*506); /* 16.580608 MHz */ m_maincpu->set_addrmap(AS_PROGRAM, &palm_state::palm_map); m_maincpu->set_dasm_override(FUNC(palm_state::palm_dasm_override)); + m_maincpu->out_port_f().set(FUNC(palm_state::palm_port_f_out)); + m_maincpu->in_port_c().set(FUNC(palm_state::palm_port_c_in)); + m_maincpu->in_port_f().set(FUNC(palm_state::palm_port_f_in)); + m_maincpu->out_pwm().set("dac", FUNC(dac_bit_interface::write)); + m_maincpu->out_spim().set(FUNC(palm_state::palm_spim_out)); + m_maincpu->in_spim().set(FUNC(palm_state::palm_spim_in)); + m_maincpu->spim_xch_trigger().set(FUNC(palm_state::palm_spim_exchange)); config.m_minimum_quantum = attotime::from_hz(60); @@ -198,7 +200,7 @@ void palm_state::palm(machine_config &config) screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); screen.set_size(160, 220); screen.set_visarea(0, 159, 0, 219); - screen.set_screen_update(MC68328_TAG, FUNC(mc68328_device::screen_update)); + screen.set_screen_update("maincpu", FUNC(mc68328_device::screen_update)); screen.set_palette("palette"); PALETTE(config, "palette", FUNC(palm_state::palm_palette), 2); @@ -208,15 +210,6 @@ void palm_state::palm(machine_config &config) DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25); voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0)); vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT); - - MC68328(config, m_lsi, 0, "maincpu"); // on-board peripherals - m_lsi->out_port_f().set(FUNC(palm_state::palm_port_f_out)); - m_lsi->in_port_c().set(FUNC(palm_state::palm_port_c_in)); - m_lsi->in_port_f().set(FUNC(palm_state::palm_port_f_in)); - m_lsi->out_pwm().set("dac", FUNC(dac_bit_interface::write)); - m_lsi->out_spim().set(FUNC(palm_state::palm_spim_out)); - m_lsi->in_spim().set(FUNC(palm_state::palm_spim_in)); - m_lsi->spim_xch_trigger().set(FUNC(palm_state::palm_spim_exchange)); } static INPUT_PORTS_START( palm ) -- cgit v1.2.3