From 1e3ee8b40d521e56831517194c78a1b708087425 Mon Sep 17 00:00:00 2001 From: angelosa Date: Sat, 17 Aug 2024 23:20:04 +0200 Subject: m6502/m4510.cpp: CPU I/O port support (backport from M6510 core) --- src/devices/cpu/m6502/m4510.cpp | 88 +++++++++++++++++++++++++++++++++++++---- src/devices/cpu/m6502/m4510.h | 19 +++++++++ src/mame/commodore/c65.cpp | 50 +++++++++++++++++------ 3 files changed, 138 insertions(+), 19 deletions(-) diff --git a/src/devices/cpu/m6502/m4510.cpp b/src/devices/cpu/m6502/m4510.cpp index 46e8994319a..02fde4bf88c 100644 --- a/src/devices/cpu/m6502/m4510.cpp +++ b/src/devices/cpu/m6502/m4510.cpp @@ -20,7 +20,10 @@ DEFINE_DEVICE_TYPE(M4510, m4510_device, "m4510", "CSG 4510") m4510_device::m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m65ce02_device(mconfig, M4510, tag, owner, clock), map_enable(0), - nomap(false) + nomap(false), + read_port(*this, 0), + write_port(*this), + dir(0), port(0), drive(0) { program_config.m_addr_width = 20; program_config.m_logaddr_width = 16; @@ -28,6 +31,14 @@ m4510_device::m4510_device(const machine_config &mconfig, const char *tag, devic sprogram_config.m_addr_width = 20; sprogram_config.m_logaddr_width = 16; sprogram_config.m_page_shift = 13; + pullup = 0x00; + floating = 0x00; +} + +void m4510_device::set_pulls(uint8_t _pullup, uint8_t _floating) +{ + pullup = _pullup; + floating = _floating; } std::unique_ptr m4510_device::create_disassembler() @@ -35,11 +46,21 @@ std::unique_ptr m4510_device::create_disassembler() return std::make_unique(); } +void m4510_device::init_port() +{ + save_item(NAME(pullup)); + save_item(NAME(floating)); + save_item(NAME(dir)); + save_item(NAME(port)); + save_item(NAME(drive)); +} + void m4510_device::device_start() { mintf = std::make_unique(this); m65ce02_device::init(); + init_port(); save_item(NAME(map_offset)); save_item(NAME(map_enable)); @@ -51,10 +72,44 @@ void m4510_device::device_reset() map_enable = 0; nomap = true; - // Wild guess, this setting makes the cpu start executing some code in the c65 driver - //map_offset[1] = 0x2e000; - //map_enable = 0x80; m65ce02_device::device_reset(); + dir = 0x00; + port = 0x00; + drive = 0x00; + update_port(); +} + +void m4510_device::update_port() +{ + drive = (port & dir) | (drive & ~dir); + write_port((port & dir) | (pullup & ~dir)); +} + +uint8_t m4510_device::get_port() +{ + return (port & dir) | (pullup & ~dir); +} + +uint8_t m4510_device::dir_r() +{ + return dir; +} + +uint8_t m4510_device::port_r() +{ + return ((read_port() | (floating & drive)) & ~dir) | (port & dir); +} + +void m4510_device::dir_w(uint8_t data) +{ + dir = data; + update_port(); +} + +void m4510_device::port_w(uint8_t data) +{ + port = data; + update_port(); } bool m4510_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) @@ -75,22 +130,41 @@ m4510_device::mi_4510::mi_4510(m4510_device *_base) uint8_t m4510_device::mi_4510::read(uint16_t adr) { - return program.read_byte(base->map(adr)); + uint8_t res = program.read_byte(base->map(adr)); + if(adr == 0x0000) + res = base->dir_r(); + else if(adr == 0x0001) + res = base->port_r(); + return res; } uint8_t m4510_device::mi_4510::read_sync(uint16_t adr) { - return csprogram.read_byte(base->map(adr)); + uint8_t res = csprogram.read_byte(base->map(adr)); + if(adr == 0x0000) + res = base->dir_r(); + else if(adr == 0x0001) + res = base->port_r(); + return res; } uint8_t m4510_device::mi_4510::read_arg(uint16_t adr) { - return cprogram.read_byte(base->map(adr)); + uint8_t res = cprogram.read_byte(base->map(adr)); + if(adr == 0x0000) + res = base->dir_r(); + else if(adr == 0x0001) + res = base->port_r(); + return res; } void m4510_device::mi_4510::write(uint16_t adr, uint8_t val) { program.write_byte(base->map(adr), val); + if(adr == 0x0000) + base->dir_w(val); + else if(adr == 0x0001) + base->port_w(val); } #include "cpu/m6502/m4510.hxx" diff --git a/src/devices/cpu/m6502/m4510.h b/src/devices/cpu/m6502/m4510.h index 6f5692fb3df..f357b237f50 100644 --- a/src/devices/cpu/m6502/m4510.h +++ b/src/devices/cpu/m6502/m4510.h @@ -26,6 +26,12 @@ public: bool get_nomap() const { return nomap; } + uint8_t get_port(); + void set_pulls(uint8_t pullup, uint8_t pulldown); + + auto read_callback() { return read_port.bind(); } + auto write_callback() { return write_port.bind(); } + protected: uint32_t map_offset[2]; uint8_t map_enable; @@ -43,6 +49,11 @@ protected: virtual void write(uint16_t adr, uint8_t val) override; }; + devcb_read8 read_port; + devcb_write8 write_port; + + uint8_t pullup, floating, dir, port, drive; + virtual void device_start() override; virtual void device_reset() override; virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override; @@ -56,6 +67,14 @@ protected: return adr; } + uint8_t dir_r(); + void dir_w(uint8_t data); + uint8_t port_r(); + void port_w(uint8_t data); + + void init_port(); + void update_port(); + #define O(o) void o ## _full(); void o ## _partial() // 4510 opcodes diff --git a/src/mame/commodore/c65.cpp b/src/mame/commodore/c65.cpp index bf60761c6f2..90fb9615f18 100644 --- a/src/mame/commodore/c65.cpp +++ b/src/mame/commodore/c65.cpp @@ -300,6 +300,9 @@ public: //, m_roma_view(*this, "roma_view") , m_romc_view(*this, "romc_view") //, m_rome_view(*this, "rome_view") + //, m_loram_view(*this, "loram_view") + //, m_hiram_view(*this, "hiram_view") + , m_charen_view(*this, "charen_view") , m_screen(*this, "screen") , m_palette(*this, "palette") , m_workram(*this, "work_ram", 0x20000, ENDIANNESS_LITTLE) @@ -334,6 +337,10 @@ private: //memory_view m_roma_view; memory_view m_romc_view; //memory_view m_rome_view; + //memory_view m_loram_view; + //memory_view m_hiram_view; + memory_view m_charen_view; + required_device m_screen; required_device m_palette; memory_share_creator m_workram; @@ -359,6 +366,8 @@ private: uint8_t cia0_portb_r(); void cia0_portb_w(uint8_t data); void cia1_porta_w(uint8_t data); + uint8_t cpu_r(); + void cpu_w(uint8_t data); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void palette_init(palette_device &palette); @@ -994,23 +1003,25 @@ void c65_state::c65_map(address_map &map) map(0x0c000, 0x0cfff).view(m_romc_view); m_romc_view[0](0x0c000, 0x0cfff).rw(FUNC(c65_state::ram_r<0x0c000>), FUNC(c65_state::ram_w<0x0c000>)); m_romc_view[1](0x0c000, 0x0cfff).rom().region("ipl", 0x0c000); - map(0x0d000, 0x0d07f).m(*this, FUNC(c65_state::vic4567_map)); + map(0x0d000, 0x0dfff).view(m_charen_view); + m_charen_view[0](0x0d000, 0x0dfff).rom().region("ipl", 0x0d000); + m_charen_view[1](0x0d000, 0x0d07f).m(*this, FUNC(c65_state::vic4567_map)); // 0x0d080, 0x0d09f FDC - map(0x0d080, 0x0d09f).lr8(NAME([] (offs_t offset) { return 0; })); + m_charen_view[1](0x0d080, 0x0d09f).lr8(NAME([] (offs_t offset) { return 0; })); // 0x0d0a0, 0x0d0ff Ram Expansion Control (REC) - map(0x0d100, 0x0d1ff).ram().w(FUNC(c65_state::palette_red_w)).share("redpal"); - map(0x0d200, 0x0d2ff).ram().w(FUNC(c65_state::palette_green_w)).share("greenpal"); - map(0x0d300, 0x0d3ff).ram().w(FUNC(c65_state::palette_blue_w)).share("bluepal"); + m_charen_view[1](0x0d100, 0x0d1ff).ram().w(FUNC(c65_state::palette_red_w)).share("redpal"); + m_charen_view[1](0x0d200, 0x0d2ff).ram().w(FUNC(c65_state::palette_green_w)).share("greenpal"); + m_charen_view[1](0x0d300, 0x0d3ff).ram().w(FUNC(c65_state::palette_blue_w)).share("bluepal"); // 0x0d400, 0x0d4*f Right SID // keyboard hold left shift will read to $d484 (?) - map(0x0d400, 0x0d41f).mirror(0x80).rw(m_sid[1], FUNC(mos6581_device::read), FUNC(mos6581_device::write)); + m_charen_view[1](0x0d400, 0x0d41f).mirror(0x80).rw(m_sid[1], FUNC(mos6581_device::read), FUNC(mos6581_device::write)); // 0x0d440, 0x0d4*f Left SID - map(0x0d440, 0x0d45f).mirror(0x80).rw(m_sid[0], FUNC(mos6581_device::read), FUNC(mos6581_device::write)); - map(0x0d600, 0x0d6ff).rw(FUNC(c65_state::uart_r), FUNC(c65_state::uart_w)); + m_charen_view[1](0x0d440, 0x0d45f).mirror(0x80).rw(m_sid[0], FUNC(mos6581_device::read), FUNC(mos6581_device::write)); + m_charen_view[1](0x0d600, 0x0d6ff).rw(FUNC(c65_state::uart_r), FUNC(c65_state::uart_w)); // 0x0d700, 0x0d7** DMAgic - map(0x0d700, 0x0d703).m(m_dma, FUNC(dmagic_f018_device::map)); + m_charen_view[1](0x0d700, 0x0d703).m(m_dma, FUNC(dmagic_f018_device::map)); // 0x0d800, 0x0d8** Color matrix - map(0x0d800, 0x0dfff).view(m_cram_view); + m_charen_view[1](0x0d800, 0x0dfff).view(m_cram_view); // maps lower 1024 bytes regardless of the setting (essentially touches $dc00 as overlay) m_cram_view[0](0x0d800, 0x0dbff).lrw8( NAME([this] (offs_t offset) { return m_cram[offset]; }), @@ -1211,11 +1222,27 @@ void c65_state::irq_check(uint8_t irq_cause) m_irqs->in_w<1>(m_irq_mask & m_irq_pending); } +uint8_t c65_state::cpu_r() +{ + return 0x07; +} + +void c65_state::cpu_w(uint8_t data) +{ +// m_loram = BIT(data, 0); +// m_hiram = BIT(data, 1); + m_charen_view.select(BIT(data, 2)); +} + + void c65_state::c65(machine_config &config) { /* basic machine hardware */ M4510(config, m_maincpu, MAIN_C65_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &c65_state::c65_map); + m_maincpu->read_callback().set(FUNC(c65_state::cpu_r)); + m_maincpu->write_callback().set(FUNC(c65_state::cpu_w)); + m_maincpu->set_pulls(0x07, 0xc0); // TODO: multiply by x8 because with a more canonical x1 no transfer will complete in time. // is this thing a mixed burst/cycle steal really? @@ -1266,9 +1293,8 @@ void c65_state::c65(machine_config &config) //m_sid->poty().set(FUNC(c64_state::sid_poty_r)); m_sid[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.50); - - // software list SOFTWARE_LIST(config, "flop_list").set_original("c65_flop"); +// SOFTWARE_LIST(config, "cart_list").set_compatible("c64_cart"); } -- cgit v1.2.3